Commit 08368132 authored by Armin Krezović's avatar Armin Krezović Committed by Pekka Paalanen

weston: Port DRM backend to new output handling API

This is a complete port of the DRM backend that uses
the recently added output handling API for output
configuration.

Output can be configured at runtime by passing the
necessary configuration parameters, which can be
filled in manually or obtained from the configuration
file using previously added functionality. It is
required that the scale and transform values are set
using the previously added functionality.

After everything has been set, output needs to be
enabled manually using weston_output_enable().

v2:

 - Added missing drmModeFreeCrtc() to drm_output_enable()
   cleanup list in case of failure.
 - Split drm_backend_disable() into drm_backend_deinit()
   to accomodate for changes in the first patch in the
   series. Moved restoring original crtc to
   drm_output_destroy().

v3:

 - Moved origcrtc allocation to drm_output_set_mode().
 - Swapped connector_get_current_mode() and
   drm_output_add_mode() calls in drm_output_set_mode()
   to match current weston.
 - Moved crtc_allocator and connector_allocator update
   from drm_output_enable() to create_output_for_connector()
   to avoid problems when more than one monitor is connected
   at startup and crtc allocator wasn't updated before
   create_output_for_connector() was called second time,
   resulting in one screen being turned off.
 - Moved crtc_allocator and connector_allocator update from
   drm_output_deinit() to drm_output_destroy(), as it
   should not be called on drm_output_disable().
 - Use weston_compositor_add_pending_output().
 - Bump weston_drm_backend_config version to 2.

v4:

 - Reset output->original_crtc to NULL if drm_output_set_mode()
   fails.
 - Remove unneeded log message when disabling an output when a
   pageflip is pending.
 - Document that create_output_for_connector() takes ownership
   of the connector.
 - Free the connector if create output conditionals are not met
   in create_outputs() and update_outputs().
Signed-off-by: default avatarArmin Krezović <krezovic.armin@gmail.com>
Reviewed-by: Pekka Paalanen's avatarPekka Paalanen <pekka.paalanen@collabora.co.uk>
parent a3666d21
......@@ -1087,48 +1087,6 @@ wet_configure_windowed_output_from_config(struct weston_output *output,
return 0;
}
static enum weston_drm_backend_output_mode
drm_configure_output(struct weston_compositor *c,
bool use_current_mode,
const char *name,
struct weston_drm_backend_output_config *config)
{
struct weston_config *wc = wet_get_config(c);
struct weston_config_section *section;
char *s;
int scale;
enum weston_drm_backend_output_mode mode =
WESTON_DRM_BACKEND_OUTPUT_PREFERRED;
section = weston_config_get_section(wc, "output", "name", name);
weston_config_section_get_string(section, "mode", &s, "preferred");
if (strcmp(s, "off") == 0) {
free(s);
return WESTON_DRM_BACKEND_OUTPUT_OFF;
}
if (use_current_mode || strcmp(s, "current") == 0) {
mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
} else if (strcmp(s, "preferred") != 0) {
config->modeline = s;
s = NULL;
}
free(s);
weston_config_section_get_int(section, "scale", &scale, 1);
config->base.scale = scale >= 1 ? scale : 1;
weston_config_section_get_string(section, "transform", &s, "normal");
if (weston_parse_transform(s, &config->base.transform) < 0)
weston_log("Invalid transform \"%s\" for output %s\n",
s, name);
free(s);
weston_config_section_get_string(section,
"gbm-format", &config->gbm_format, NULL);
weston_config_section_get_string(section, "seat", &config->seat, "");
return mode;
}
static void
configure_input_device(struct weston_compositor *compositor,
struct libinput_device *device)
......@@ -1153,6 +1111,65 @@ configure_input_device(struct weston_compositor *compositor,
}
}
static void
drm_backend_output_configure(struct wl_listener *listener, void *data)
{
struct weston_output *output = data;
struct weston_config *wc = wet_get_config(output->compositor);
struct weston_config_section *section;
const struct weston_drm_output_api *api = weston_drm_output_get_api(output->compositor);
enum weston_drm_backend_output_mode mode =
WESTON_DRM_BACKEND_OUTPUT_PREFERRED;
char *s;
char *modeline = NULL;
char *gbm_format = NULL;
char *seat = NULL;
if (!api) {
weston_log("Cannot use weston_drm_output_api.\n");
return;
}
section = weston_config_get_section(wc, "output", "name", output->name);
weston_config_section_get_string(section, "mode", &s, "preferred");
if (strcmp(s, "off") == 0) {
weston_output_disable(output);
free(s);
return;
} else if (strcmp(s, "current") == 0) {
mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
} else if (strcmp(s, "preferred") != 0) {
modeline = s;
s = NULL;
}
free(s);
if (api->set_mode(output, mode, modeline) < 0) {
weston_log("Cannot configure an output using weston_drm_output_api.\n");
free(modeline);
return;
}
free(modeline);
wet_output_set_scale(output, section, 1, 0);
wet_output_set_transform(output, section, WL_OUTPUT_TRANSFORM_NORMAL, UINT32_MAX);
weston_config_section_get_string(section,
"gbm-format", &gbm_format, NULL);
api->set_gbm_format(output, gbm_format);
free(gbm_format);
weston_config_section_get_string(section, "seat", &seat, "");
api->set_seat(output, seat);
free(seat);
weston_output_enable(output);
}
static int
load_drm_backend(struct weston_compositor *c,
int *argc, char **argv, struct weston_config *wc)
......@@ -1178,12 +1195,13 @@ load_drm_backend(struct weston_compositor *c,
config.base.struct_version = WESTON_DRM_BACKEND_CONFIG_VERSION;
config.base.struct_size = sizeof(struct weston_drm_backend_config);
config.configure_output = drm_configure_output;
config.configure_device = configure_input_device;
ret = weston_compositor_load_backend(c, WESTON_BACKEND_DRM,
&config.base);
wet_set_pending_output_handler(c, drm_backend_output_configure);
free(config.gbm_format);
free(config.seat_id);
......
This diff is collapsed.
......@@ -29,12 +29,13 @@
#define WESTON_COMPOSITOR_DRM_H
#include "compositor.h"
#include "plugin-registry.h"
#ifdef __cplusplus
extern "C" {
#endif
#define WESTON_DRM_BACKEND_CONFIG_VERSION 1
#define WESTON_DRM_BACKEND_CONFIG_VERSION 2
struct libinput_device;
......@@ -51,8 +52,17 @@ enum weston_drm_backend_output_mode {
WESTON_DRM_BACKEND_OUTPUT_PREFERRED,
};
struct weston_drm_backend_output_config {
struct weston_backend_output_config base;
#define WESTON_DRM_OUTPUT_API_NAME "weston_drm_output_api_v1"
struct weston_drm_output_api {
/** The mode to be used by the output. Refer to the documentation
* of WESTON_DRM_BACKEND_OUTPUT_PREFERRED for details.
*
* Returns 0 on success, -1 on failure.
*/
int (*set_mode)(struct weston_output *output,
enum weston_drm_backend_output_mode mode,
const char *modeline);
/** The pixel format to be used by the output. Valid values are:
* - NULL - The format set at backend creation time will be used;
......@@ -60,15 +70,26 @@ struct weston_drm_backend_output_config {
* - "rgb565"
* - "xrgb2101010"
*/
char *gbm_format;
void (*set_gbm_format)(struct weston_output *output,
const char *gbm_format);
/** The seat to be used by the output. Set to NULL to use the
* default seat. */
char *seat;
/** The modeline to be used by the output. Refer to the documentation
* of WESTON_DRM_BACKEND_OUTPUT_PREFERRED for details. */
char *modeline;
* default seat.
*/
void (*set_seat)(struct weston_output *output,
const char *seat);
};
static inline const struct weston_drm_output_api *
weston_drm_output_get_api(struct weston_compositor *compositor)
{
const void *api;
api = weston_plugin_api_get(compositor, WESTON_DRM_OUTPUT_API_NAME,
sizeof(struct weston_drm_output_api));
return (const struct weston_drm_output_api *)api;
}
/** The backend configuration struct.
*
* weston_drm_backend_config contains the configuration used by a DRM
......@@ -109,17 +130,6 @@ struct weston_drm_backend_config {
*/
char *gbm_format;
/** Callback used to configure the outputs.
*
* This function will be called by the backend when a new DRM
* output needs to be configured.
*/
enum weston_drm_backend_output_mode
(*configure_output)(struct weston_compositor *compositor,
bool use_current_mode,
const char *name,
struct weston_drm_backend_output_config *output_config);
/** Callback used to configure input devices.
*
* This function will be called by the backend when a new input device
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment