headless, gl-renderer: support pbuffer outputs

Use the surfaceless platform in the headless backend to initialize the
GL-renderer and create pbuffer outputs. This allows headless backend to use
GL-renderer, even hardware accelerated.

This paves way for exercising GL-renderer in CI and using the Weston test suite
to test hardware GL ES implementations.

Relates to: https://gitlab.freedesktop.org/wayland/weston/issues/278

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
Pekka Paalanen
2019-09-20 14:23:12 +03:00
committed by Pekka Paalanen
parent 209187491b
commit 5104d7b2af
4 changed files with 154 additions and 1 deletions
+43
View File
@@ -3142,6 +3142,48 @@ gl_renderer_output_window_create(struct weston_output *output,
return ret;
}
static int
gl_renderer_output_pbuffer_create(struct weston_output *output,
int width,
int height,
const uint32_t *drm_formats,
unsigned drm_formats_count)
{
struct gl_renderer *gr = get_renderer(output->compositor);
EGLConfig pbuffer_config;
EGLSurface egl_surface;
int ret;
EGLint pbuffer_attribs[] = {
EGL_WIDTH, width,
EGL_HEIGHT, height,
EGL_NONE
};
pbuffer_config = gl_renderer_get_egl_config(gr, EGL_PBUFFER_BIT,
drm_formats,
drm_formats_count);
if (pbuffer_config == EGL_NO_CONFIG_KHR) {
weston_log("failed to choose EGL config for PbufferSurface\n");
return -1;
}
log_egl_config_info(gr->egl_display, pbuffer_config);
egl_surface = eglCreatePbufferSurface(gr->egl_display, pbuffer_config,
pbuffer_attribs);
if (egl_surface == EGL_NO_SURFACE) {
weston_log("failed to create egl surface\n");
gl_renderer_print_egl_error_state();
return -1;
}
ret = gl_renderer_output_create(output, egl_surface);
if (ret < 0)
eglDestroySurface(gr->egl_display, egl_surface);
return ret;
}
static void
gl_renderer_output_destroy(struct weston_output *output)
{
@@ -3728,6 +3770,7 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
WL_EXPORT struct gl_renderer_interface gl_renderer_interface = {
.display_create = gl_renderer_display_create,
.output_window_create = gl_renderer_output_window_create,
.output_pbuffer_create = gl_renderer_output_pbuffer_create,
.output_destroy = gl_renderer_output_destroy,
.output_set_border = gl_renderer_output_set_border,
.create_fence_fd = gl_renderer_create_fence_fd,
+27
View File
@@ -135,6 +135,33 @@ struct gl_renderer_interface {
const uint32_t *drm_formats,
unsigned drm_formats_count);
/**
* Attach GL-renderer to the output with internal pixel storage
*
* \param output The output to create a rendering surface for.
* \param width Width of the rendering surface in pixels.
* \param height Height of the rendering surface in pixels.
* \param drm_formats Array of DRM pixel formats that are acceptable.
* \param drm_formats_count The drm_formats array length.
* \return 0 on success, -1 on failure.
*
* This function creates the renderer data structures needed to repaint
* the output. The repaint results will be kept internal and can only
* be accessed through e.g. screen capture.
*
* The first format in drm_formats that matches any EGLConfig
* determines which EGLConfig is chosen. See \c display_create about
* how the matching works and the possible limitations.
*
* This function should be used only if \c display_create was called
* with \c EGL_PBUFFER_BIT in \c egl_surface_type.
*/
int (*output_pbuffer_create)(struct weston_output *output,
int width,
int height,
const uint32_t *drm_formats,
unsigned drm_formats_count);
void (*output_destroy)(struct weston_output *output);
/* Sets the output border.