Add official fx renderer (#3)

This commit is contained in:
William McKinnon 2022-08-13 02:14:23 -04:00 committed by GitHub
parent 06f19c81a4
commit cf1ed777ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 497 additions and 33 deletions

1
.gitignore vendored
View file

@ -2,6 +2,7 @@ install_manifest.txt
*.swp
*.o
*.a
.cache/
bin/
test/
build/

View file

@ -1,11 +1,10 @@
# swaypower: A Beautiful Sway Fork
# swayFX: A Beautiful Sway Fork
Sway is an incredible window manager, and certainly one of if the the most well established wayland window managers. However, it is restricted in its feature set to include only what i3 included. This fork expands sway's featureset to include the following:
+ **[Scratchpad treated as minimize](https://github.com/WillPower3309/swaypower/commit/f6aac41efee81c3edfda14be8ddb375827c81d9e)**: Allows docks, or panels with a taskbar, to correctly interpret minimize / unminimize requests ([thanks to LCBCrion](https://github.com/swaywm/sway/issues/6457))
+ **Default to not compiling swaybar**: Many users replace swaybar with the far more capable [waybar](https://github.com/Alexays/Waybar), this repo cuts out the bloat by not including swaybar by default
+ **Add a nix flake to the repo**: Allows nixos users to easily contribute to and test this repo
Sway is an incredible window manager, and certainly one of the most well established wayland window managers. However, it is restricted to only include the functionality that existed in i3. This fork ditches the simple wlr_renderer, and replaces it with a fancy GLES2 renderer with functionality borrowed from the original simple renderer and [Hyprland](https://github.com/vaxerski/Hyprland). This, along with a couple of minor changes, expands sway's featureset to include the following:
+ **Scratchpad treated as minimize**: Allows docks, or panels with a taskbar, to correctly interpret minimize / unminimize requests ([thanks to LCBCrion](https://github.com/swaywm/sway/issues/6457))
+ **Default to not compiling swaybar**: Many users replace swaybar with the far more capable [waybar](https://github.com/Alexays/Waybar), swayFX cuts out the bloat by not including swaybar by default
+ **Add a nix flake to the repo**: Allows nixos users to easily contribute to and test this project
## Roadmap:
+ fade in / out animations

View file

@ -22,7 +22,7 @@
];
buildInputs = with pkgs; [
wayland libxkbcommon pcre json_c libevdev pango cairo libinput libcap pam gdk-pixbuf librsvg
wayland libxkbcommon pcre2 json_c libevdev pango cairo libinput libcap pam gdk-pixbuf librsvg
wayland-protocols libdrm wlroots dbus xwayland
# wlroots
libGL pixman xorg.xcbutilwm xorg.libX11 libcap xorg.xcbutilimage xorg.xcbutilerrors mesa

View file

@ -0,0 +1,51 @@
#ifndef _SWAY_OPENGL_H
#define _SWAY_OPENGL_H
#include <GLES2/gl2.h>
struct gles2_tex_shader {
GLuint program;
GLint proj;
GLint tex;
GLint alpha;
GLint pos_attrib;
GLint tex_attrib;
};
struct fx_renderer {
struct wlr_egl *egl;
float projection[9];
// Shaders
struct {
struct {
GLuint program;
GLint proj;
GLint color;
GLint pos_attrib;
} quad;
struct gles2_tex_shader tex_rgba;
struct gles2_tex_shader tex_rgbx;
struct gles2_tex_shader tex_ext;
} shaders;
};
struct fx_renderer *fx_renderer_create(struct wlr_egl *egl);
void fx_renderer_begin(struct fx_renderer *renderer, uint32_t width, uint32_t height);
void fx_renderer_end();
void fx_renderer_clear(const float color[static 4]);
void fx_renderer_scissor(struct wlr_box *box);
bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer,
struct wlr_texture *wlr_texture, const struct wlr_fbox *box,
const float matrix[static 9], float alpha);
bool fx_render_texture_with_matrix(struct fx_renderer *renderer,
struct wlr_texture *wlr_texture, const float matrix[static 9], float alpha);
#endif

View file

@ -35,7 +35,8 @@ struct sway_server {
struct wlr_backend *backend;
// secondary headless backend used for creating virtual outputs on-the-fly
struct wlr_backend *headless_backend;
struct wlr_renderer *renderer;
struct wlr_renderer *wlr_renderer;
struct fx_renderer *renderer;
struct wlr_allocator *allocator;
struct wlr_compositor *compositor;

397
sway/desktop/fx_renderer.c Normal file
View file

@ -0,0 +1,397 @@
/*
primarily stolen from:
- https://gitlab.freedesktop.org/wlroots/wlroots/-/tree/master/render/gles2
- https://github.com/vaxerski/Hyprland/blob/main/src/render/OpenGL.cpp
*/
#define _POSIX_C_SOURCE 200809L
#include <assert.h>
#include <GLES2/gl2.h>
#include <stdlib.h>
#include <wlr/backend.h>
#include <wlr/render/egl.h>
#include <wlr/render/gles2.h>
#include <wlr/types/wlr_matrix.h>
#include <wlr/util/box.h>
#include "log.h"
#include "sway/desktop/fx_renderer.h"
#include "sway/output.h"
#include "sway/server.h"
/************************
Shaders
*************************/
// Colored quads
const GLchar quad_vertex_src[] =
"uniform mat3 proj;\n"
"uniform vec4 color;\n"
"attribute vec2 pos;\n"
"attribute vec2 texcoord;\n"
"varying vec4 v_color;\n"
"varying vec2 v_texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);\n"
" v_color = color;\n"
" v_texcoord = texcoord;\n"
"}\n";
const GLchar quad_fragment_src[] =
"precision mediump float;\n"
"varying vec4 v_color;\n"
"varying vec2 v_texcoord;\n"
"\n"
"void main() {\n"
" gl_FragColor = v_color;\n"
"}\n";
// Textured quads
const GLchar tex_vertex_src[] =
"uniform mat3 proj;\n"
"attribute vec2 pos;\n"
"attribute vec2 texcoord;\n"
"varying vec2 v_texcoord;\n"
"\n"
"void main() {\n"
" gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);\n"
" v_texcoord = texcoord;\n"
"}\n";
const GLchar tex_fragment_src_rgba[] =
"precision mediump float;\n"
"varying vec2 v_texcoord;\n"
"uniform sampler2D tex;\n"
"uniform float alpha;\n"
"\n"
"void main() {\n"
" gl_FragColor = texture2D(tex, v_texcoord) * alpha;\n"
"}\n";
const GLchar tex_fragment_src_rgbx[] =
"precision mediump float;\n"
"varying vec2 v_texcoord;\n"
"uniform sampler2D tex;\n"
"uniform float alpha;\n"
"\n"
"void main() {\n"
" gl_FragColor = vec4(texture2D(tex, v_texcoord).rgb, 1.0) * alpha;\n"
"}\n";
const GLchar tex_fragment_src_external[] =
"#extension GL_OES_EGL_image_external : require\n\n"
"precision mediump float;\n"
"varying vec2 v_texcoord;\n"
"uniform samplerExternalOES texture0;\n"
"uniform float alpha;\n"
"\n"
"void main() {\n"
" gl_FragColor = texture2D(texture0, v_texcoord) * alpha;\n"
"}\n";
/************************
Matrix Consts
*************************/
/*
static const GLfloat flip_180[] = {
1.0f, 0.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
};
*/
static const GLfloat verts[] = {
1, 0, // top right
0, 0, // top left
1, 1, // bottom right
0, 1, // bottom left
};
/************************
General Functions
*************************/
static GLuint compile_shader(GLuint type, const GLchar *src) {
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
GLint ok;
glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
if (ok == GL_FALSE) {
glDeleteShader(shader);
shader = 0;
}
return shader;
}
static GLuint link_program(const GLchar *vert_src, const GLchar *frag_src) {
GLuint vert = compile_shader(GL_VERTEX_SHADER, vert_src);
if (!vert) {
goto error;
}
GLuint frag = compile_shader(GL_FRAGMENT_SHADER, frag_src);
if (!frag) {
glDeleteShader(vert);
goto error;
}
GLuint prog = glCreateProgram();
glAttachShader(prog, vert);
glAttachShader(prog, frag);
glLinkProgram(prog);
glDetachShader(prog, vert);
glDetachShader(prog, frag);
glDeleteShader(vert);
glDeleteShader(frag);
GLint ok;
glGetProgramiv(prog, GL_LINK_STATUS, &ok);
if (ok == GL_FALSE) {
glDeleteProgram(prog);
goto error;
}
return prog;
error:
return 0;
}
// TODO: Hyprland way?
// TODO: instead of server, have param be server->backend like wlr_renderer_autocreate
struct fx_renderer *fx_renderer_create(struct wlr_egl *egl) {
struct fx_renderer *renderer = calloc(1, sizeof(struct fx_renderer));
if (renderer == NULL) {
return NULL;
}
// TODO: wlr_egl_make_current or eglMakeCurrent?
// TODO: assert instead of conditional statement?
if (!wlr_egl_make_current(egl)) {
sway_log(SWAY_ERROR, "GLES2 RENDERER: Could not make EGL current");
return NULL;
}
// TODO: needed?
renderer->egl = egl;
// get extensions
const char *exts_str = (const char *)glGetString(GL_EXTENSIONS);
if (exts_str == NULL) {
sway_log(SWAY_ERROR, "GLES2 RENDERER: Failed to get GL_EXTENSIONS");
return NULL;
}
sway_log(SWAY_INFO, "Creating swayfx GLES2 renderer");
sway_log(SWAY_INFO, "Using %s", glGetString(GL_VERSION));
sway_log(SWAY_INFO, "GL vendor: %s", glGetString(GL_VENDOR));
sway_log(SWAY_INFO, "GL renderer: %s", glGetString(GL_RENDERER));
sway_log(SWAY_INFO, "Supported GLES2 extensions: %s", exts_str);
// TODO: gl checks
// init shaders
GLuint prog;
prog = link_program(quad_vertex_src, quad_fragment_src);
renderer->shaders.quad.program = prog;
if (!renderer->shaders.quad.program) {
goto error;
}
renderer->shaders.quad.proj = glGetUniformLocation(prog, "proj");
renderer->shaders.quad.color = glGetUniformLocation(prog, "color");
renderer->shaders.quad.pos_attrib = glGetAttribLocation(prog, "pos");
prog = link_program(tex_vertex_src, tex_fragment_src_rgba);
renderer->shaders.tex_rgba.program = prog;
if (!renderer->shaders.tex_rgba.program) {
goto error;
}
renderer->shaders.tex_rgba.proj = glGetUniformLocation(prog, "proj");
renderer->shaders.tex_rgba.tex = glGetUniformLocation(prog, "tex");
renderer->shaders.tex_rgba.alpha = glGetUniformLocation(prog, "alpha");
renderer->shaders.tex_rgba.pos_attrib = glGetAttribLocation(prog, "pos");
renderer->shaders.tex_rgba.tex_attrib = glGetAttribLocation(prog, "texcoord");
prog = link_program(tex_vertex_src, tex_fragment_src_rgbx);
renderer->shaders.tex_rgbx.program = prog;
if (!renderer->shaders.tex_rgbx.program) {
goto error;
}
renderer->shaders.tex_rgbx.proj = glGetUniformLocation(prog, "proj");
renderer->shaders.tex_rgbx.tex = glGetUniformLocation(prog, "tex");
renderer->shaders.tex_rgbx.alpha = glGetUniformLocation(prog, "alpha");
renderer->shaders.tex_rgbx.pos_attrib = glGetAttribLocation(prog, "pos");
renderer->shaders.tex_rgbx.tex_attrib = glGetAttribLocation(prog, "texcoord");
prog = link_program(tex_vertex_src, tex_fragment_src_external);
renderer->shaders.tex_ext.program = prog;
if (!renderer->shaders.tex_ext.program) {
goto error;
}
renderer->shaders.tex_ext.proj = glGetUniformLocation(prog, "proj");
renderer->shaders.tex_ext.tex = glGetUniformLocation(prog, "tex");
renderer->shaders.tex_ext.alpha = glGetUniformLocation(prog, "alpha");
renderer->shaders.tex_ext.pos_attrib = glGetAttribLocation(prog, "pos");
renderer->shaders.tex_ext.tex_attrib = glGetAttribLocation(prog, "texcoord");
// TODO: if remove renderer->egl, replace below with r->egl
wlr_egl_unset_current(renderer->egl);
sway_log(SWAY_INFO, "GLES2 RENDERER: Shaders Initialized Successfully");
return renderer;
error:
glDeleteProgram(renderer->shaders.quad.program);
glDeleteProgram(renderer->shaders.tex_rgba.program);
glDeleteProgram(renderer->shaders.tex_rgbx.program);
glDeleteProgram(renderer->shaders.tex_ext.program);
wlr_egl_unset_current(renderer->egl);
// TODO: more freeing?
free(renderer);
sway_log(SWAY_ERROR, "GLES2 RENDERER: Error Initializing Shaders");
return NULL;
}
void fx_renderer_begin(struct fx_renderer *renderer, uint32_t width, uint32_t height) {
//push_gles2_debug(renderer);
glViewport(0, 0, width, height);
// refresh projection matrix
wlr_matrix_projection(renderer->projection, width, height,
WL_OUTPUT_TRANSFORM_FLIPPED_180);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
//pop_gles2_debug(renderer);
}
void fx_renderer_end() {
}
void fx_renderer_clear(const float color[static 4]) {
glClearColor(color[0], color[1], color[2], color[3]);
glClear(GL_COLOR_BUFFER_BIT);
}
void fx_renderer_scissor(struct wlr_box *box) {
if (box) {
glScissor(box->x, box->y, box->width, box->height);
glEnable(GL_SCISSOR_TEST);
} else {
glDisable(GL_SCISSOR_TEST);
}
}
/************************
Rendering Functions
*************************/
bool fx_render_subtexture_with_matrix(struct fx_renderer *renderer,
struct wlr_texture *wlr_texture, const struct wlr_fbox *box,
const float matrix[static 9], float alpha) {
assert(wlr_texture_is_gles2(wlr_texture));
struct wlr_gles2_texture_attribs texture_attrs;
wlr_gles2_texture_get_attribs(wlr_texture, &texture_attrs);
struct gles2_tex_shader *shader = NULL;
switch (texture_attrs.target) {
case GL_TEXTURE_2D:
if (texture_attrs.has_alpha) {
shader = &renderer->shaders.tex_rgba;
} else {
shader = &renderer->shaders.tex_rgbx;
}
break;
/*
case GL_TEXTURE_EXTERNAL_OES:
shader = &renderer->shaders.tex_ext;
// TODO: ADD ME ONCE EXTS ADDED TO RENDERER
if (!renderer->exts.OES_egl_image_external) {
sway_log(SWAY_ERROR, "Failed to render texture: "
"GL_TEXTURE_EXTERNAL_OES not supported");
return false;
}
break;
*/
default:
sway_log(SWAY_ERROR, "Aborting render");
abort();
}
float gl_matrix[9];
wlr_matrix_multiply(gl_matrix, renderer->projection, matrix);
// OpenGL ES 2 requires the glUniformMatrix3fv transpose parameter to be set
// to GL_FALSE
wlr_matrix_transpose(gl_matrix, gl_matrix);
// push_gles2_debug(renderer);
if (!texture_attrs.has_alpha && alpha == 1.0) {
glDisable(GL_BLEND);
} else {
glEnable(GL_BLEND);
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture_attrs.target, texture_attrs.tex);
glTexParameteri(texture_attrs.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glUseProgram(shader->program);
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, gl_matrix);
glUniform1i(shader->tex, 0);
glUniform1f(shader->alpha, alpha);
const GLfloat x1 = box->x / wlr_texture->width;
const GLfloat y1 = box->y / wlr_texture->height;
const GLfloat x2 = (box->x + box->width) / wlr_texture->width;
const GLfloat y2 = (box->y + box->height) / wlr_texture->height;
const GLfloat texcoord[] = {
x2, y1, // top right
x1, y1, // top left
x2, y2, // bottom right
x1, y2, // bottom left
};
glVertexAttribPointer(shader->pos_attrib, 2, GL_FLOAT, GL_FALSE, 0, verts);
glVertexAttribPointer(shader->tex_attrib, 2, GL_FLOAT, GL_FALSE, 0, texcoord);
glEnableVertexAttribArray(shader->pos_attrib);
glEnableVertexAttribArray(shader->tex_attrib);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableVertexAttribArray(shader->pos_attrib);
glDisableVertexAttribArray(shader->tex_attrib);
glBindTexture(texture_attrs.target, 0);
// pop_gles2_debug(renderer);
return true;
}
bool fx_render_texture_with_matrix(struct fx_renderer *renderer,
struct wlr_texture *wlr_texture, const float matrix[static 9], float alpha) {
struct wlr_fbox box = {
.x = 0,
.y = 0,
.width = wlr_texture->width,
.height = wlr_texture->height,
};
return fx_render_subtexture_with_matrix(renderer, wlr_texture, &box, matrix, alpha);
}

View file

@ -31,6 +31,7 @@
#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "sway/desktop/fx_renderer.h"
struct sway_output *output_by_name_or_id(const char *name_or_id) {
for (int i = 0; i < root->outputs->length; ++i) {
@ -868,7 +869,7 @@ void handle_new_output(struct wl_listener *listener, void *data) {
}
if (!wlr_output_init_render(wlr_output, server->allocator,
server->renderer)) {
server->wlr_renderer)) {
sway_log(SWAY_ERROR, "Failed to init output render");
return;
}

View file

@ -17,6 +17,7 @@
#include "log.h"
#include "config.h"
#include "sway/config.h"
#include "sway/desktop/fx_renderer.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
#include "sway/layers.h"
@ -52,7 +53,8 @@ static int scale_length(int length, int offset, float scale) {
static void scissor_output(struct wlr_output *wlr_output,
pixman_box32_t *rect) {
struct wlr_renderer *renderer = wlr_output->renderer;
struct sway_output *output = wlr_output->data;
struct fx_renderer *renderer = output->server->renderer;
assert(renderer);
struct wlr_box box = {
@ -69,7 +71,7 @@ static void scissor_output(struct wlr_output *wlr_output,
wlr_output_transform_invert(wlr_output->transform);
wlr_box_transform(&box, &box, transform, ow, oh);
wlr_renderer_scissor(renderer, &box);
fx_renderer_scissor(&box);
}
static void set_scale_filter(struct wlr_output *wlr_output,
@ -100,8 +102,8 @@ static void render_texture(struct wlr_output *wlr_output,
pixman_region32_t *output_damage, struct wlr_texture *texture,
const struct wlr_fbox *src_box, const struct wlr_box *dst_box,
const float matrix[static 9], float alpha) {
struct wlr_renderer *renderer = wlr_output->renderer;
struct sway_output *output = wlr_output->data;
struct fx_renderer *renderer = output->server->renderer;
pixman_region32_t damage;
pixman_region32_init(&damage);
@ -119,9 +121,9 @@ static void render_texture(struct wlr_output *wlr_output,
scissor_output(wlr_output, &rects[i]);
set_scale_filter(wlr_output, texture, output->scale_filter);
if (src_box != NULL) {
wlr_render_subtexture_with_matrix(renderer, texture, src_box, matrix, alpha);
fx_render_subtexture_with_matrix(renderer, texture, src_box, matrix, alpha);
} else {
wlr_render_texture_with_matrix(renderer, texture, matrix, alpha);
fx_render_texture_with_matrix(renderer, texture, matrix, alpha);
}
}
@ -162,8 +164,7 @@ static void render_surface_iterator(struct sway_output *output,
}
scale_box(&dst_box, wlr_output->scale);
render_texture(wlr_output, output_damage, texture,
&src_box, &dst_box, matrix, alpha);
render_texture(wlr_output, output_damage, texture, &src_box, &dst_box, matrix, alpha);
wlr_presentation_surface_sampled_on_output(server.presentation, surface,
wlr_output);
@ -1027,7 +1028,8 @@ static void render_seatops(struct sway_output *output,
void output_render(struct sway_output *output, struct timespec *when,
pixman_region32_t *damage) {
struct wlr_output *wlr_output = output->wlr_output;
struct wlr_renderer *renderer = output->server->renderer;
struct wlr_renderer *wlr_renderer = output->server->wlr_renderer;
struct fx_renderer *renderer = output->server->renderer;
struct sway_workspace *workspace = output->current.active_workspace;
if (workspace == NULL) {
@ -1039,7 +1041,7 @@ void output_render(struct sway_output *output, struct timespec *when,
fullscreen_con = workspace->current.fullscreen;
}
wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height);
fx_renderer_begin(renderer, wlr_output->width, wlr_output->height);
if (debug.damage == DAMAGE_RERENDER) {
int width, height;
@ -1053,7 +1055,7 @@ void output_render(struct sway_output *output, struct timespec *when,
}
if (debug.damage == DAMAGE_HIGHLIGHT) {
wlr_renderer_clear(renderer, (float[]){1, 1, 0, 1});
fx_renderer_clear((float[]){1, 1, 0, 1});
}
if (output_has_opaque_overlay_layer_surface(output)) {
@ -1067,7 +1069,7 @@ void output_render(struct sway_output *output, struct timespec *when,
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
wlr_renderer_clear(renderer, clear_color);
fx_renderer_clear(clear_color);
}
if (fullscreen_con->view) {
@ -1099,7 +1101,7 @@ void output_render(struct sway_output *output, struct timespec *when,
pixman_box32_t *rects = pixman_region32_rectangles(damage, &nrects);
for (int i = 0; i < nrects; ++i) {
scissor_output(wlr_output, &rects[i]);
wlr_renderer_clear(renderer, clear_color);
fx_renderer_clear(clear_color);
}
render_layer_toplevel(output, damage,
@ -1139,9 +1141,11 @@ render_overlay:
render_drag_icons(output, damage, &root->drag_icons);
renderer_end:
wlr_renderer_scissor(renderer, NULL);
fx_renderer_scissor(NULL);
wlr_renderer_begin(wlr_renderer, wlr_output->width, wlr_output->height);
wlr_output_render_software_cursors(wlr_output, damage);
wlr_renderer_end(renderer);
wlr_renderer_end(wlr_renderer);
fx_renderer_end();
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);

View file

@ -12,6 +12,7 @@ sway_sources = files(
'xdg_decoration.c',
'desktop/desktop.c',
'desktop/fx_renderer.c',
'desktop/idle_inhibit_v1.c',
'desktop/layer_shell.c',
'desktop/output.c',

View file

@ -9,6 +9,7 @@
#include <wlr/backend/multi.h>
#include <wlr/backend/session.h>
#include <wlr/config.h>
#include <wlr/render/gles2.h>
#include <wlr/render/wlr_renderer.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_data_control_v1.h>
@ -38,6 +39,7 @@
#include "list.h"
#include "log.h"
#include "sway/config.h"
#include "sway/desktop/fx_renderer.h"
#include "sway/desktop/idle_inhibit_v1.h"
#include "sway/input/input-manager.h"
#include "sway/output.h"
@ -75,29 +77,35 @@ static void handle_drm_lease_request(struct wl_listener *listener, void *data) {
bool server_init(struct sway_server *server) {
sway_log(SWAY_DEBUG, "Initializing Wayland server");
server->renderer = wlr_renderer_autocreate(server->backend);
server->wlr_renderer = wlr_renderer_autocreate(server->backend);
if (!server->wlr_renderer) {
sway_log(SWAY_ERROR, "Failed to create wlr_renderer");
return false;
}
struct wlr_egl *egl = wlr_gles2_renderer_get_egl(server->wlr_renderer);
server->renderer = fx_renderer_create(egl);
if (!server->renderer) {
sway_log(SWAY_ERROR, "Failed to create renderer");
sway_log(SWAY_ERROR, "Failed to create fx_renderer");
return false;
}
wlr_renderer_init_wl_shm(server->renderer, server->wl_display);
wlr_renderer_init_wl_shm(server->wlr_renderer, server->wl_display);
if (wlr_renderer_get_dmabuf_texture_formats(server->renderer) != NULL) {
wlr_drm_create(server->wl_display, server->renderer);
if (wlr_renderer_get_dmabuf_texture_formats(server->wlr_renderer) != NULL) {
wlr_drm_create(server->wl_display, server->wlr_renderer);
server->linux_dmabuf_v1 =
wlr_linux_dmabuf_v1_create(server->wl_display, server->renderer);
wlr_linux_dmabuf_v1_create(server->wl_display, server->wlr_renderer);
}
server->allocator = wlr_allocator_autocreate(server->backend,
server->renderer);
server->wlr_renderer);
if (!server->allocator) {
sway_log(SWAY_ERROR, "Failed to create allocator");
return false;
}
server->compositor = wlr_compositor_create(server->wl_display,
server->renderer);
server->wlr_renderer);
server->compositor_new_surface.notify = handle_compositor_new_surface;
wl_signal_add(&server->compositor->events.new_surface,
&server->compositor_new_surface);

View file

@ -16,6 +16,7 @@
#include "pango.h"
#include "sway/config.h"
#include "sway/desktop.h"
#include "sway/desktop/fx_renderer.h"
#include "sway/desktop/transaction.h"
#include "sway/input/input-manager.h"
#include "sway/input/seat.h"
@ -1103,10 +1104,10 @@ static void set_fullscreen(struct sway_container *con, bool enable) {
// TODO: add wlroots helpers for all of this stuff
const struct wlr_drm_format_set *renderer_formats =
wlr_renderer_get_dmabuf_texture_formats(server.renderer);
wlr_renderer_get_dmabuf_texture_formats(server.wlr_renderer);
assert(renderer_formats);
int renderer_drm_fd = wlr_renderer_get_drm_fd(server.renderer);
int renderer_drm_fd = wlr_renderer_get_drm_fd(server.wlr_renderer);
int backend_drm_fd = wlr_backend_get_drm_fd(wlr_output->backend);
if (renderer_drm_fd < 0 || backend_drm_fd < 0) {
return;