Skip to content

Commit

Permalink
gl-renderer: implement basic gl-renderer-api
Browse files Browse the repository at this point in the history
  • Loading branch information
ammen99 committed Feb 27, 2018
1 parent 213b651 commit 1eefc13
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 2 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Expand Up @@ -300,6 +300,7 @@ libwestoninclude_HEADERS = \
libweston/compositor-wayland.h \
libweston/compositor-x11.h \
libweston/windowed-output-api.h \
libweston/gl-renderer-api.h \
libweston/plugin-registry.h \
libweston/timeline-object.h \
shared/matrix.h \
Expand Down
101 changes: 101 additions & 0 deletions libweston/gl-renderer-api.h
@@ -0,0 +1,101 @@
/*
* Copyright © 2017 Ilia Bozhinov
*
* 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 (including the
* next paragraph) 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.
*/

#ifndef WESTON_GL_RENDERER_API_H
#define WESTON_GL_RENDERER_API_H

#ifdef __cplusplus
extern "C" {
#endif

#include "plugin-registry.h"
#include <stdbool.h>
#include <pixman.h>

struct weston_compositor;
struct weston_output;
struct weston_surface;

#define WESTON_GL_RENDERER_API_NAME "weston_gl_renderer_api_v1"

typedef bool (*custom_renderer_func_t) (struct weston_output*, pixman_region32_t*);
typedef void (*post_render_func_t) (struct weston_output*);

struct weston_gl_renderer_api {
/* Set custom renderer function
*
* \param ec The compositor instance
* \param renderer The function which should be called at each repaint cycle
*
* The renderer function should return true if it has painted the output and the
* in-built gl-renderer should leave the output as is. Otherwise, the gl-renderer proceeds
* as if there is no custom renderer.
*/
void (*set_custom_renderer) (struct weston_compositor *ec, custom_renderer_func_t renderer);

/* Set custom post-renderer function
*
* \param ec The compositor instance
* \param post The function which should be called right after each repaint
*
* The post function is called after each rendered frame, regardless of whether
* a custom renderer or the in-built gl-renderer was used
*/
void (*set_post_render) (struct weston_compositor *ec, post_render_func_t post);

/* Schedule output repaint
*
* \param output The output for which a repaint is to be scheduled
*
* Unlike weston_output_schedule_repaint, this function must ensure that
* the gl-renderer will be invoked at the next frame. Useful when used together
* with custom renderer/post function, as it must bypass any optimizations in
* the drm-backend
*/
void (*schedule_repaint) (struct weston_output *output);

/* Get the gl-renderer's textures for a given surface
*
* \param surface The surface whose textures are queried
* \param n_tex The number of textures for this surface
*/
void* (*surface_get_textures)(struct weston_surface *surface, int *n_tex);
};

static inline const struct weston_gl_renderer_api *
weston_gl_renderer_get_api(struct weston_compositor *compositor)
{
const void *api;
api = weston_plugin_api_get(compositor, WESTON_GL_RENDERER_API_NAME,
sizeof(struct weston_gl_renderer_api));

return (const struct weston_gl_renderer_api *)api;
}

#ifdef __cplusplus
}
#endif

#endif /* WESTON_GL_RENDERER_API_H */
83 changes: 81 additions & 2 deletions libweston/gl-renderer.c
Expand Up @@ -60,6 +60,8 @@
#include "shared/timespec-util.h"
#include "weston-egl-ext.h"

#include "gl-renderer-api.h"

struct gl_shader {
GLuint program;
GLuint vertex_shader, fragment_shader;
Expand Down Expand Up @@ -250,6 +252,9 @@ struct gl_renderer {
PFNEGLCREATESYNCKHRPROC create_sync;
PFNEGLDESTROYSYNCKHRPROC destroy_sync;
PFNEGLDUPNATIVEFENCEFDANDROIDPROC dup_native_fence_fd;

custom_renderer_func_t custom_renderer;
post_render_func_t post_render;
};

enum timeline_render_point_type {
Expand Down Expand Up @@ -411,6 +416,56 @@ timeline_submit_render_sync(struct gl_renderer *gr,
gr->destroy_sync(gr->egl_display, sync);
}

static inline void
gl_set_custom_renderer(struct weston_compositor *ec, custom_renderer_func_t renderer)
{
struct gl_renderer *gr = get_renderer(ec);
gr->custom_renderer = renderer;
}

static inline void
gl_set_post_render(struct weston_compositor *ec, post_render_func_t post_render)
{
struct gl_renderer *gr = get_renderer(ec);
gr->post_render = post_render;
}

static inline void
gl_schedule_repaint(struct weston_output *output)
{
pixman_region32_t current_damage;

pixman_region32_init(&current_damage);
pixman_region32_intersect(&current_damage,
&output->compositor->primary_plane.damage,
&output->region);

if (!pixman_region32_not_empty(&current_damage))
{
pixman_region32_union_rect(&output->compositor->primary_plane.damage,
&output->compositor->primary_plane.damage,
output->x, output->y, 1, 1);
}

weston_output_schedule_repaint(output);
}

static inline void *
gl_surface_get_textures(struct weston_surface *surface, int *n_tex)
{
struct gl_surface_state *gs = get_surface_state(surface);

*n_tex = gs->num_textures;
return gs->textures;
}

static const struct weston_gl_renderer_api gl_renderer_api = {
gl_set_custom_renderer,
gl_set_post_render,
gl_schedule_repaint,
gl_surface_get_textures
};

static struct egl_image*
egl_image_create(struct gl_renderer *gr, EGLenum target,
EGLClientBuffer buffer, const EGLint *attribs)
Expand Down Expand Up @@ -916,6 +971,7 @@ draw_view(struct weston_view *ev, struct weston_output *output,
shader_uniforms(&gr->solid_shader, ev, output);
}

gr->current_shader = NULL;
use_shader(gr, gs->shader);
shader_uniforms(gs->shader, ev, output);

Expand Down Expand Up @@ -957,6 +1013,7 @@ draw_view(struct weston_view *ev, struct weston_output *output,
* that forces texture alpha = 1.0.
* Xwayland surfaces need this.
*/
gr->current_shader = NULL;
use_shader(gr, &gr->texture_shader_rgbx);
shader_uniforms(&gr->texture_shader_rgbx, ev, output);
}
Expand All @@ -970,6 +1027,7 @@ draw_view(struct weston_view *ev, struct weston_output *output,
}

if (pixman_region32_not_empty(&surface_blend)) {
gr->current_shader = NULL;
use_shader(gr, gs->shader);
glEnable(GL_BLEND);
repaint_region(ev, &repaint, &surface_blend);
Expand Down Expand Up @@ -1095,6 +1153,7 @@ draw_output_borders(struct weston_output *output,
full_height = output->current_mode->height + top->height + bottom->height;

glDisable(GL_BLEND);
gr->current_shader = NULL;
use_shader(gr, shader);

glViewport(0, 0, full_width, full_height);
Expand Down Expand Up @@ -1288,7 +1347,14 @@ gl_renderer_repaint_output(struct weston_output *output,
pixman_region32_union(&total_damage, &buffer_damage, output_damage);
border_damage |= go->border_status;

repaint_views(output, &total_damage);
bool swap_buffers_with_damage = gr->swap_buffers_with_damage;
if (!gr->custom_renderer || !gr->custom_renderer(output, output_damage))
repaint_views(output, &total_damage);
else
swap_buffers_with_damage = false;

if (gr->post_render)
gr->post_render(output);

pixman_region32_fini(&total_damage);
pixman_region32_fini(&buffer_damage);
Expand All @@ -1300,7 +1366,7 @@ gl_renderer_repaint_output(struct weston_output *output,

end_render_sync = timeline_create_render_sync(gr);

if (gr->swap_buffers_with_damage) {
if (swap_buffers_with_damage) {
pixman_region32_init(&buffer_damage);
weston_transformed_region(output->width, output->height,
output->transform,
Expand Down Expand Up @@ -2445,6 +2511,8 @@ gl_renderer_surface_copy_content(struct weston_surface *surface,

glViewport(0, 0, cw, ch);
glDisable(GL_BLEND);

gr->current_shader = NULL;
use_shader(gr, gs->shader);
if (gs->y_inverted)
proj = projmat_normal;
Expand Down Expand Up @@ -3241,6 +3309,7 @@ static const EGLint gl_renderer_opaque_attribs[] = {
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
Expand All @@ -3251,6 +3320,7 @@ static const EGLint gl_renderer_alpha_attribs[] = {
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, 1,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
Expand Down Expand Up @@ -3357,6 +3427,7 @@ gl_renderer_create_pbuffer_surface(struct gl_renderer *gr) {
EGL_GREEN_SIZE, 1,
EGL_BLUE_SIZE, 1,
EGL_ALPHA_SIZE, 0,
EGL_DEPTH_SIZE, 1,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
Expand Down Expand Up @@ -3413,6 +3484,7 @@ gl_renderer_display_create(struct weston_compositor *ec, EGLenum platform,
gr->base.surface_get_content_size =
gl_renderer_surface_get_content_size;
gr->base.surface_copy_content = gl_renderer_surface_copy_content;

gr->egl_display = NULL;

/* extension_suffix is supported */
Expand Down Expand Up @@ -3658,6 +3730,12 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
if (compile_shaders(ec))
return -1;

gr->custom_renderer = NULL;
gr->post_render = NULL;
if (weston_plugin_api_register(ec, WESTON_GL_RENDERER_API_NAME,
&gl_renderer_api, sizeof(gl_renderer_api)) < 0)
return -1;

gr->fragment_binding =
weston_compositor_add_debug_binding(ec, KEY_S,
fragment_debug_binding,
Expand All @@ -3683,6 +3761,7 @@ gl_renderer_setup(struct weston_compositor *ec, EGLSurface egl_surface)
return 0;
}


WL_EXPORT struct gl_renderer_interface gl_renderer_interface = {
.opaque_attribs = gl_renderer_opaque_attribs,
.alpha_attribs = gl_renderer_alpha_attribs,
Expand Down

0 comments on commit 1eefc13

Please sign in to comment.