mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-04-13 08:22:16 -04:00
Merge branch 'master' into 'master'
render: add gles3 renderer See merge request wlroots/wlroots!5183
This commit is contained in:
commit
c0063a29d6
31 changed files with 499 additions and 334 deletions
|
|
@ -9,7 +9,7 @@ wlroots reads these environment variables
|
||||||
* *WLR_XWAYLAND*: specifies the path to an Xwayland binary to be used (instead
|
* *WLR_XWAYLAND*: specifies the path to an Xwayland binary to be used (instead
|
||||||
of following shell search semantics for "Xwayland")
|
of following shell search semantics for "Xwayland")
|
||||||
* *WLR_RENDERER*: forces the creation of a specified renderer (available
|
* *WLR_RENDERER*: forces the creation of a specified renderer (available
|
||||||
renderers: gles2, pixman, vulkan)
|
renderers: gles2, gles3, pixman, vulkan)
|
||||||
* *WLR_RENDER_DRM_DEVICE*: specifies the DRM node to use for
|
* *WLR_RENDER_DRM_DEVICE*: specifies the DRM node to use for
|
||||||
hardware-accelerated renderers.
|
hardware-accelerated renderers.
|
||||||
* *WLR_RENDER_NO_EXPLICIT_SYNC*: set to 1 to disable explicit synchronization
|
* *WLR_RENDER_NO_EXPLICIT_SYNC*: set to 1 to disable explicit synchronization
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ endif
|
||||||
if not features.get('xwayland')
|
if not features.get('xwayland')
|
||||||
exclude_files += 'xwayland.h'
|
exclude_files += 'xwayland.h'
|
||||||
endif
|
endif
|
||||||
if not features.get('gles2-renderer')
|
if not features.get('gles2-renderer') and not features.get('gles3-renderer')
|
||||||
exclude_files += ['render/egl.h', 'render/gles2.h']
|
exclude_files += ['render/egl.h', 'render/gles.h']
|
||||||
endif
|
endif
|
||||||
if not features.get('vulkan-renderer')
|
if not features.get('vulkan-renderer')
|
||||||
exclude_files += 'render/vulkan.h'
|
exclude_files += 'render/vulkan.h'
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ struct wlr_egl {
|
||||||
bool has_modifiers;
|
bool has_modifiers;
|
||||||
struct wlr_drm_format_set dmabuf_texture_formats;
|
struct wlr_drm_format_set dmabuf_texture_formats;
|
||||||
struct wlr_drm_format_set dmabuf_render_formats;
|
struct wlr_drm_format_set dmabuf_render_formats;
|
||||||
|
enum egl_version version;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_egl_context {
|
struct wlr_egl_context {
|
||||||
|
|
@ -61,7 +62,7 @@ struct wlr_egl_context {
|
||||||
*
|
*
|
||||||
* Will attempt to load all possibly required API functions.
|
* Will attempt to load all possibly required API functions.
|
||||||
*/
|
*/
|
||||||
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd);
|
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd, enum egl_version version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees all related EGL resources, makes the context not-current and
|
* Frees all related EGL resources, makes the context not-current and
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef RENDER_GLES2_H
|
#ifndef RENDER_GLES_H
|
||||||
#define RENDER_GLES2_H
|
#define RENDER_GLES_H
|
||||||
|
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES2/gl2ext.h>
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <wlr/render/egl.h>
|
#include <wlr/render/egl.h>
|
||||||
#include <wlr/render/gles2.h>
|
#include <wlr/render/gles.h>
|
||||||
#include <wlr/render/interface.h>
|
#include <wlr/render/interface.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/render/wlr_texture.h>
|
#include <wlr/render/wlr_texture.h>
|
||||||
|
|
@ -21,14 +21,14 @@
|
||||||
// https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23144
|
// https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/23144
|
||||||
typedef void (GL_APIENTRYP PFNGLGETINTEGER64VEXTPROC) (GLenum pname, GLint64 *data);
|
typedef void (GL_APIENTRYP PFNGLGETINTEGER64VEXTPROC) (GLenum pname, GLint64 *data);
|
||||||
|
|
||||||
struct wlr_gles2_pixel_format {
|
struct wlr_gles_pixel_format {
|
||||||
uint32_t drm_format;
|
uint32_t drm_format;
|
||||||
// optional field, if empty then internalformat = format
|
// optional field, if empty then internalformat = format
|
||||||
GLint gl_internalformat;
|
GLint gl_internalformat;
|
||||||
GLint gl_format, gl_type;
|
GLint gl_format, gl_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_gles2_tex_shader {
|
struct wlr_gles_tex_shader {
|
||||||
GLuint program;
|
GLuint program;
|
||||||
GLint proj;
|
GLint proj;
|
||||||
GLint tex_proj;
|
GLint tex_proj;
|
||||||
|
|
@ -37,7 +37,7 @@ struct wlr_gles2_tex_shader {
|
||||||
GLint pos_attrib;
|
GLint pos_attrib;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_gles2_renderer {
|
struct wlr_gles_renderer {
|
||||||
struct wlr_renderer wlr_renderer;
|
struct wlr_renderer wlr_renderer;
|
||||||
|
|
||||||
struct wlr_egl *egl;
|
struct wlr_egl *egl;
|
||||||
|
|
@ -80,28 +80,28 @@ struct wlr_gles2_renderer {
|
||||||
GLint color;
|
GLint color;
|
||||||
GLint pos_attrib;
|
GLint pos_attrib;
|
||||||
} quad;
|
} quad;
|
||||||
struct wlr_gles2_tex_shader tex_rgba;
|
struct wlr_gles_tex_shader tex_rgba;
|
||||||
struct wlr_gles2_tex_shader tex_rgbx;
|
struct wlr_gles_tex_shader tex_rgbx;
|
||||||
struct wlr_gles2_tex_shader tex_ext;
|
struct wlr_gles_tex_shader tex_ext;
|
||||||
} shaders;
|
} shaders;
|
||||||
|
|
||||||
struct wl_list buffers; // wlr_gles2_buffer.link
|
struct wl_list buffers; // wlr_gles_buffer.link
|
||||||
struct wl_list textures; // wlr_gles2_texture.link
|
struct wl_list textures; // wlr_gles_texture.link
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_gles2_render_timer {
|
struct wlr_gles_render_timer {
|
||||||
struct wlr_render_timer base;
|
struct wlr_render_timer base;
|
||||||
struct wlr_gles2_renderer *renderer;
|
struct wlr_gles_renderer *renderer;
|
||||||
struct timespec cpu_start;
|
struct timespec cpu_start;
|
||||||
struct timespec cpu_end;
|
struct timespec cpu_end;
|
||||||
GLuint id;
|
GLuint id;
|
||||||
GLint64 gl_cpu_end;
|
GLint64 gl_cpu_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_gles2_buffer {
|
struct wlr_gles_buffer {
|
||||||
struct wlr_buffer *buffer;
|
struct wlr_buffer *buffer;
|
||||||
struct wlr_gles2_renderer *renderer;
|
struct wlr_gles_renderer *renderer;
|
||||||
struct wl_list link; // wlr_gles2_renderer.buffers
|
struct wl_list link; // wlr_gles_renderer.buffers
|
||||||
bool external_only;
|
bool external_only;
|
||||||
|
|
||||||
EGLImageKHR image;
|
EGLImageKHR image;
|
||||||
|
|
@ -112,10 +112,10 @@ struct wlr_gles2_buffer {
|
||||||
struct wlr_addon addon;
|
struct wlr_addon addon;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_gles2_texture {
|
struct wlr_gles_texture {
|
||||||
struct wlr_texture wlr_texture;
|
struct wlr_texture wlr_texture;
|
||||||
struct wlr_gles2_renderer *renderer;
|
struct wlr_gles_renderer *renderer;
|
||||||
struct wl_list link; // wlr_gles2_renderer.textures
|
struct wl_list link; // wlr_gles_renderer.textures
|
||||||
|
|
||||||
GLenum target;
|
GLenum target;
|
||||||
|
|
||||||
|
|
@ -128,49 +128,49 @@ struct wlr_gles2_texture {
|
||||||
bool has_alpha;
|
bool has_alpha;
|
||||||
|
|
||||||
uint32_t drm_format; // for mutable textures only, used to interpret upload data
|
uint32_t drm_format; // for mutable textures only, used to interpret upload data
|
||||||
struct wlr_gles2_buffer *buffer; // for DMA-BUF imports only
|
struct wlr_gles_buffer *buffer; // for DMA-BUF imports only
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_gles2_render_pass {
|
struct wlr_gles_render_pass {
|
||||||
struct wlr_render_pass base;
|
struct wlr_render_pass base;
|
||||||
struct wlr_gles2_buffer *buffer;
|
struct wlr_gles_buffer *buffer;
|
||||||
float projection_matrix[9];
|
float projection_matrix[9];
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
struct wlr_gles2_render_timer *timer;
|
struct wlr_gles_render_timer *timer;
|
||||||
struct wlr_drm_syncobj_timeline *signal_timeline;
|
struct wlr_drm_syncobj_timeline *signal_timeline;
|
||||||
uint64_t signal_point;
|
uint64_t signal_point;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
bool is_gles_pixel_format_supported(const struct wlr_gles_renderer *renderer,
|
||||||
const struct wlr_gles2_pixel_format *format);
|
const struct wlr_gles_pixel_format *format);
|
||||||
const struct wlr_gles2_pixel_format *get_gles2_format_from_drm(uint32_t fmt);
|
const struct wlr_gles_pixel_format *get_gles_format_from_drm(uint32_t fmt);
|
||||||
const struct wlr_gles2_pixel_format *get_gles2_format_from_gl(
|
const struct wlr_gles_pixel_format *get_gles_format_from_gl(
|
||||||
GLint gl_format, GLint gl_type, bool alpha);
|
GLint gl_format, GLint gl_type, bool alpha);
|
||||||
void get_gles2_shm_formats(const struct wlr_gles2_renderer *renderer,
|
void get_gles_shm_formats(const struct wlr_gles_renderer *renderer,
|
||||||
struct wlr_drm_format_set *out);
|
struct wlr_drm_format_set *out);
|
||||||
|
|
||||||
GLuint gles2_buffer_get_fbo(struct wlr_gles2_buffer *buffer);
|
GLuint gles_buffer_get_fbo(struct wlr_gles_buffer *buffer);
|
||||||
|
|
||||||
struct wlr_gles2_renderer *gles2_get_renderer(
|
struct wlr_gles_renderer *gles_get_renderer(
|
||||||
struct wlr_renderer *wlr_renderer);
|
struct wlr_renderer *wlr_renderer);
|
||||||
struct wlr_gles2_render_timer *gles2_get_render_timer(
|
struct wlr_gles_render_timer *gles_get_render_timer(
|
||||||
struct wlr_render_timer *timer);
|
struct wlr_render_timer *timer);
|
||||||
struct wlr_gles2_texture *gles2_get_texture(
|
struct wlr_gles_texture *gles_get_texture(
|
||||||
struct wlr_texture *wlr_texture);
|
struct wlr_texture *wlr_texture);
|
||||||
struct wlr_gles2_buffer *gles2_buffer_get_or_create(struct wlr_gles2_renderer *renderer,
|
struct wlr_gles_buffer *gles_buffer_get_or_create(struct wlr_gles_renderer *renderer,
|
||||||
struct wlr_buffer *wlr_buffer);
|
struct wlr_buffer *wlr_buffer);
|
||||||
|
|
||||||
struct wlr_texture *gles2_texture_from_buffer(struct wlr_renderer *wlr_renderer,
|
struct wlr_texture *gles_texture_from_buffer(struct wlr_renderer *wlr_renderer,
|
||||||
struct wlr_buffer *buffer);
|
struct wlr_buffer *buffer);
|
||||||
void gles2_texture_destroy(struct wlr_gles2_texture *texture);
|
void gles_texture_destroy(struct wlr_gles_texture *texture);
|
||||||
|
|
||||||
void push_gles2_debug_(struct wlr_gles2_renderer *renderer,
|
void push_gles_debug_(struct wlr_gles_renderer *renderer,
|
||||||
const char *file, const char *func);
|
const char *file, const char *func);
|
||||||
#define push_gles2_debug(renderer) push_gles2_debug_(renderer, _WLR_FILENAME, __func__)
|
#define push_gles_debug(renderer) push_gles_debug_(renderer, _WLR_FILENAME, __func__)
|
||||||
void pop_gles2_debug(struct wlr_gles2_renderer *renderer);
|
void pop_gles_debug(struct wlr_gles_renderer *renderer);
|
||||||
|
|
||||||
struct wlr_gles2_render_pass *begin_gles2_buffer_pass(struct wlr_gles2_buffer *buffer,
|
struct wlr_gles_render_pass *begin_gles_buffer_pass(struct wlr_gles_buffer *buffer,
|
||||||
struct wlr_egl_context *prev_ctx, struct wlr_gles2_render_timer *timer,
|
struct wlr_egl_context *prev_ctx, struct wlr_gles_render_timer *timer,
|
||||||
struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point);
|
struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -27,9 +27,16 @@
|
||||||
* Whether the GLES2 renderer is compile-time enabled. Equivalent to the
|
* Whether the GLES2 renderer is compile-time enabled. Equivalent to the
|
||||||
* pkg-config "have_gles2_renderer" variable.
|
* pkg-config "have_gles2_renderer" variable.
|
||||||
*
|
*
|
||||||
* Required for <wlr/render/gles2.h>.
|
* Required for <wlr/render/gles.h>.
|
||||||
*/
|
*/
|
||||||
#mesondefine WLR_HAS_GLES2_RENDERER
|
#mesondefine WLR_HAS_GLES2_RENDERER
|
||||||
|
/**
|
||||||
|
* Whether the GLES3 renderer is compile-time enabled. Equivalent to the
|
||||||
|
* pkg-config "have_gles3_renderer" variable.
|
||||||
|
*
|
||||||
|
* Required for <wlr/render/gles.h>.
|
||||||
|
*/
|
||||||
|
#mesondefine WLR_HAS_GLES3_RENDERER
|
||||||
/**
|
/**
|
||||||
* Whether the Vulkan renderer is compile-time enabled. Equivalent to the
|
* Whether the Vulkan renderer is compile-time enabled. Equivalent to the
|
||||||
* pkg-config "have_vulkan_renderer" variable.
|
* pkg-config "have_vulkan_renderer" variable.
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
struct wlr_egl;
|
struct wlr_egl;
|
||||||
|
|
||||||
|
enum egl_version { GLES2 = 2, GLES3 = 3 };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a struct wlr_egl with an existing EGL display and context.
|
* Create a struct wlr_egl with an existing EGL display and context.
|
||||||
*
|
*
|
||||||
|
|
@ -35,7 +37,7 @@ struct wlr_egl;
|
||||||
* initialization.
|
* initialization.
|
||||||
*/
|
*/
|
||||||
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
||||||
EGLContext context);
|
EGLContext context, enum egl_version version);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the EGL display used by the struct wlr_egl.
|
* Get the EGL display used by the struct wlr_egl.
|
||||||
|
|
|
||||||
54
include/wlr/render/gles.h
Normal file
54
include/wlr/render/gles.h
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* This an unstable interface of wlroots. No guarantees are made regarding the
|
||||||
|
* future consistency of this API.
|
||||||
|
*/
|
||||||
|
#ifndef WLR_USE_UNSTABLE
|
||||||
|
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WLR_RENDER_GLES2_H
|
||||||
|
#define WLR_RENDER_GLES2_H
|
||||||
|
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
|
||||||
|
#include <wlr/render/wlr_renderer.h>
|
||||||
|
|
||||||
|
struct wlr_egl;
|
||||||
|
|
||||||
|
enum egl_version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OpenGL ES renderer.
|
||||||
|
*
|
||||||
|
* Care must be taken to avoid stepping each other's toes with EGL contexts:
|
||||||
|
* the current EGL is global state. The GLES renderer operations will save
|
||||||
|
* and restore any previous EGL context when called. A render pass is seen as
|
||||||
|
* a single operation.
|
||||||
|
*
|
||||||
|
* The GLES renderer doesn't support arbitrarily nested render passes. It
|
||||||
|
* supports a subset only: after a nested render pass is created, any parent
|
||||||
|
* render pass can't be used before the nested render pass is submitted.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct wlr_renderer *wlr_gles_renderer_create_with_drm_fd(int drm_fd,
|
||||||
|
enum egl_version version);
|
||||||
|
struct wlr_renderer *wlr_gles_renderer_create(struct wlr_egl *egl);
|
||||||
|
|
||||||
|
struct wlr_egl *wlr_gles_renderer_get_egl(struct wlr_renderer *renderer);
|
||||||
|
bool wlr_gles_renderer_check_ext(struct wlr_renderer *renderer, const char *ext);
|
||||||
|
GLuint wlr_gles_renderer_get_buffer_fbo(struct wlr_renderer *renderer, struct wlr_buffer *buffer);
|
||||||
|
|
||||||
|
struct wlr_gles_texture_attribs {
|
||||||
|
GLenum target; /* either GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES */
|
||||||
|
GLuint tex;
|
||||||
|
|
||||||
|
bool has_alpha;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool wlr_renderer_is_gles(struct wlr_renderer *wlr_renderer);
|
||||||
|
bool wlr_render_timer_is_gles(struct wlr_render_timer *timer);
|
||||||
|
bool wlr_texture_is_gles(struct wlr_texture *texture);
|
||||||
|
void wlr_gles_texture_get_attribs(struct wlr_texture *texture,
|
||||||
|
struct wlr_gles_texture_attribs *attribs);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
/*
|
|
||||||
* This an unstable interface of wlroots. No guarantees are made regarding the
|
|
||||||
* future consistency of this API.
|
|
||||||
*/
|
|
||||||
#ifndef WLR_USE_UNSTABLE
|
|
||||||
#error "Add -DWLR_USE_UNSTABLE to enable unstable wlroots features"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef WLR_RENDER_GLES2_H
|
|
||||||
#define WLR_RENDER_GLES2_H
|
|
||||||
|
|
||||||
#include <GLES2/gl2.h>
|
|
||||||
|
|
||||||
#include <wlr/render/wlr_renderer.h>
|
|
||||||
|
|
||||||
struct wlr_egl;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* OpenGL ES 2 renderer.
|
|
||||||
*
|
|
||||||
* Care must be taken to avoid stepping each other's toes with EGL contexts:
|
|
||||||
* the current EGL is global state. The GLES2 renderer operations will save
|
|
||||||
* and restore any previous EGL context when called. A render pass is seen as
|
|
||||||
* a single operation.
|
|
||||||
*
|
|
||||||
* The GLES2 renderer doesn't support arbitrarily nested render passes. It
|
|
||||||
* supports a subset only: after a nested render pass is created, any parent
|
|
||||||
* render pass can't be used before the nested render pass is submitted.
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct wlr_renderer *wlr_gles2_renderer_create_with_drm_fd(int drm_fd);
|
|
||||||
struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl);
|
|
||||||
|
|
||||||
struct wlr_egl *wlr_gles2_renderer_get_egl(struct wlr_renderer *renderer);
|
|
||||||
bool wlr_gles2_renderer_check_ext(struct wlr_renderer *renderer, const char *ext);
|
|
||||||
GLuint wlr_gles2_renderer_get_buffer_fbo(struct wlr_renderer *renderer, struct wlr_buffer *buffer);
|
|
||||||
|
|
||||||
struct wlr_gles2_texture_attribs {
|
|
||||||
GLenum target; /* either GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES */
|
|
||||||
GLuint tex;
|
|
||||||
|
|
||||||
bool has_alpha;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool wlr_renderer_is_gles2(struct wlr_renderer *wlr_renderer);
|
|
||||||
bool wlr_render_timer_is_gles2(struct wlr_render_timer *timer);
|
|
||||||
bool wlr_texture_is_gles2(struct wlr_texture *texture);
|
|
||||||
void wlr_gles2_texture_get_attribs(struct wlr_texture *texture,
|
|
||||||
struct wlr_gles2_texture_attribs *attribs);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -72,6 +72,7 @@ features = {
|
||||||
'libinput-backend': false,
|
'libinput-backend': false,
|
||||||
'xwayland': false,
|
'xwayland': false,
|
||||||
'gles2-renderer': false,
|
'gles2-renderer': false,
|
||||||
|
'gles3-renderer': false,
|
||||||
'vulkan-renderer': false,
|
'vulkan-renderer': false,
|
||||||
'gbm-allocator': false,
|
'gbm-allocator': false,
|
||||||
'udmabuf-allocator': false,
|
'udmabuf-allocator': false,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ option('xcb-errors', type: 'feature', value: 'auto', description: 'Use xcb-error
|
||||||
option('xwayland', type: 'feature', value: 'auto', yield: true, description: 'Enable support for X11 applications')
|
option('xwayland', type: 'feature', value: 'auto', yield: true, description: 'Enable support for X11 applications')
|
||||||
option('examples', type: 'boolean', value: true, description: 'Build example applications')
|
option('examples', type: 'boolean', value: true, description: 'Build example applications')
|
||||||
option('icon_directory', description: 'Location used to look for cursors (default: ${datadir}/icons)', type: 'string', value: '')
|
option('icon_directory', description: 'Location used to look for cursors (default: ${datadir}/icons)', type: 'string', value: '')
|
||||||
option('renderers', type: 'array', choices: ['auto', 'gles2', 'vulkan'], value: ['auto'], description: 'Select built-in renderers')
|
option('renderers', type: 'array', choices: ['auto', 'gles2', 'gles3', 'vulkan'], value: ['auto'], description: 'Select built-in renderers')
|
||||||
option('backends', type: 'array', choices: ['auto', 'drm', 'libinput', 'x11'], value: ['auto'], description: 'Select built-in backends')
|
option('backends', type: 'array', choices: ['auto', 'drm', 'libinput', 'x11'], value: ['auto'], description: 'Select built-in backends')
|
||||||
option('allocators', type: 'array', choices: ['auto', 'gbm', 'udmabuf'], value: ['auto'],
|
option('allocators', type: 'array', choices: ['auto', 'gbm', 'udmabuf'], value: ['auto'],
|
||||||
description: 'Select built-in allocators')
|
description: 'Select built-in allocators')
|
||||||
|
|
|
||||||
14
render/egl.c
14
render/egl.c
|
|
@ -191,7 +191,7 @@ static void init_dmabuf_formats(struct wlr_egl *egl) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_egl *egl_create(void) {
|
static struct wlr_egl *egl_create(enum egl_version version) {
|
||||||
const char *client_exts_str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
const char *client_exts_str = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
|
||||||
if (client_exts_str == NULL) {
|
if (client_exts_str == NULL) {
|
||||||
if (eglGetError() == EGL_BAD_DISPLAY) {
|
if (eglGetError() == EGL_BAD_DISPLAY) {
|
||||||
|
|
@ -257,6 +257,8 @@ static struct wlr_egl *egl_create(void) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
egl->version = version;
|
||||||
|
|
||||||
return egl;
|
return egl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -411,7 +413,7 @@ static bool egl_init(struct wlr_egl *egl, EGLenum platform,
|
||||||
size_t atti = 0;
|
size_t atti = 0;
|
||||||
EGLint attribs[7];
|
EGLint attribs[7];
|
||||||
attribs[atti++] = EGL_CONTEXT_CLIENT_VERSION;
|
attribs[atti++] = EGL_CONTEXT_CLIENT_VERSION;
|
||||||
attribs[atti++] = 2;
|
attribs[atti++] = egl->version;
|
||||||
|
|
||||||
// Request a high priority context if possible
|
// Request a high priority context if possible
|
||||||
// TODO: only do this if we're running as the DRM master
|
// TODO: only do this if we're running as the DRM master
|
||||||
|
|
@ -555,10 +557,10 @@ static int open_render_node(int drm_fd) {
|
||||||
return render_fd;
|
return render_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd) {
|
struct wlr_egl *wlr_egl_create_with_drm_fd(int drm_fd, enum egl_version version) {
|
||||||
bool allow_software = drm_fd < 0;
|
bool allow_software = drm_fd < 0;
|
||||||
|
|
||||||
struct wlr_egl *egl = egl_create();
|
struct wlr_egl *egl = egl_create(version);
|
||||||
if (egl == NULL) {
|
if (egl == NULL) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create EGL context");
|
wlr_log(WLR_ERROR, "Failed to create EGL context");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -615,7 +617,7 @@ error:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
||||||
EGLContext context) {
|
EGLContext context, enum egl_version version) {
|
||||||
EGLint client_type;
|
EGLint client_type;
|
||||||
if (!eglQueryContext(display, context, EGL_CONTEXT_CLIENT_TYPE, &client_type) ||
|
if (!eglQueryContext(display, context, EGL_CONTEXT_CLIENT_TYPE, &client_type) ||
|
||||||
client_type != EGL_OPENGL_ES_API) {
|
client_type != EGL_OPENGL_ES_API) {
|
||||||
|
|
@ -630,7 +632,7 @@ struct wlr_egl *wlr_egl_create_with_context(EGLDisplay display,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_egl *egl = egl_create();
|
struct wlr_egl *egl = egl_create(version);
|
||||||
if (egl == NULL) {
|
if (egl == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
26
render/gles/meson.build
Normal file
26
render/gles/meson.build
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
glesv2 = dependency('glesv2', required: 'gles2' in renderers)
|
||||||
|
glesv3 = dependency('glesv2', required: 'gles3' in renderers)
|
||||||
|
|
||||||
|
if not ((glesv2.found() or glesv3.found()) and internal_features['egl'])
|
||||||
|
subdir_done()
|
||||||
|
endif
|
||||||
|
|
||||||
|
glslang = find_program('glslang', 'glslangValidator', native: true, required: false, disabler: true)
|
||||||
|
|
||||||
|
if glesv2.found()
|
||||||
|
features += { 'gles2-renderer': true }
|
||||||
|
wlr_deps += glesv2
|
||||||
|
endif
|
||||||
|
if glesv3.found()
|
||||||
|
features += { 'gles3-renderer': true }
|
||||||
|
wlr_deps += glesv3
|
||||||
|
endif
|
||||||
|
|
||||||
|
wlr_files += files(
|
||||||
|
'pass.c',
|
||||||
|
'pixel_format.c',
|
||||||
|
'renderer.c',
|
||||||
|
'texture.c',
|
||||||
|
)
|
||||||
|
|
||||||
|
subdir('shaders')
|
||||||
|
|
@ -6,26 +6,26 @@
|
||||||
#include <wlr/render/drm_syncobj.h>
|
#include <wlr/render/drm_syncobj.h>
|
||||||
#include <wlr/util/transform.h>
|
#include <wlr/util/transform.h>
|
||||||
#include "render/egl.h"
|
#include "render/egl.h"
|
||||||
#include "render/gles2.h"
|
#include "render/gles.h"
|
||||||
#include "util/matrix.h"
|
#include "util/matrix.h"
|
||||||
|
|
||||||
#define MAX_QUADS 86 // 4kb
|
#define MAX_QUADS 86 // 4kb
|
||||||
|
|
||||||
static const struct wlr_render_pass_impl render_pass_impl;
|
static const struct wlr_render_pass_impl render_pass_impl;
|
||||||
|
|
||||||
static struct wlr_gles2_render_pass *get_render_pass(struct wlr_render_pass *wlr_pass) {
|
static struct wlr_gles_render_pass *get_render_pass(struct wlr_render_pass *wlr_pass) {
|
||||||
assert(wlr_pass->impl == &render_pass_impl);
|
assert(wlr_pass->impl == &render_pass_impl);
|
||||||
struct wlr_gles2_render_pass *pass = wl_container_of(wlr_pass, pass, base);
|
struct wlr_gles_render_pass *pass = wl_container_of(wlr_pass, pass, base);
|
||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
||||||
struct wlr_gles2_render_pass *pass = get_render_pass(wlr_pass);
|
struct wlr_gles_render_pass *pass = get_render_pass(wlr_pass);
|
||||||
struct wlr_gles2_renderer *renderer = pass->buffer->renderer;
|
struct wlr_gles_renderer *renderer = pass->buffer->renderer;
|
||||||
struct wlr_gles2_render_timer *timer = pass->timer;
|
struct wlr_gles_render_timer *timer = pass->timer;
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
|
|
||||||
if (timer) {
|
if (timer) {
|
||||||
// clear disjoint flag
|
// clear disjoint flag
|
||||||
|
|
@ -65,7 +65,7 @@ static bool render_pass_submit(struct wlr_render_pass *wlr_pass) {
|
||||||
out:
|
out:
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
wlr_egl_restore_context(&pass->prev_ctx);
|
wlr_egl_restore_context(&pass->prev_ctx);
|
||||||
|
|
||||||
wlr_drm_syncobj_timeline_unref(pass->signal_timeline);
|
wlr_drm_syncobj_timeline_unref(pass->signal_timeline);
|
||||||
|
|
@ -166,11 +166,11 @@ static void setup_blending(enum wlr_render_blend_mode mode) {
|
||||||
|
|
||||||
static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
|
static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
|
||||||
const struct wlr_render_texture_options *options) {
|
const struct wlr_render_texture_options *options) {
|
||||||
struct wlr_gles2_render_pass *pass = get_render_pass(wlr_pass);
|
struct wlr_gles_render_pass *pass = get_render_pass(wlr_pass);
|
||||||
struct wlr_gles2_renderer *renderer = pass->buffer->renderer;
|
struct wlr_gles_renderer *renderer = pass->buffer->renderer;
|
||||||
struct wlr_gles2_texture *texture = gles2_get_texture(options->texture);
|
struct wlr_gles_texture *texture = gles_get_texture(options->texture);
|
||||||
|
|
||||||
struct wlr_gles2_tex_shader *shader = NULL;
|
struct wlr_gles_tex_shader *shader = NULL;
|
||||||
|
|
||||||
switch (texture->target) {
|
switch (texture->target) {
|
||||||
case GL_TEXTURE_2D:
|
case GL_TEXTURE_2D:
|
||||||
|
|
@ -201,7 +201,7 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
|
||||||
src_fbox.width /= options->texture->width;
|
src_fbox.width /= options->texture->width;
|
||||||
src_fbox.height /= options->texture->height;
|
src_fbox.height /= options->texture->height;
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
|
|
||||||
if (options->wait_timeline != NULL) {
|
if (options->wait_timeline != NULL) {
|
||||||
int sync_file_fd =
|
int sync_file_fd =
|
||||||
|
|
@ -250,19 +250,19 @@ static void render_pass_add_texture(struct wlr_render_pass *wlr_pass,
|
||||||
render(&dst_box, options->clip, shader->pos_attrib);
|
render(&dst_box, options->clip, shader->pos_attrib);
|
||||||
|
|
||||||
glBindTexture(texture->target, 0);
|
glBindTexture(texture->target, 0);
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_pass_add_rect(struct wlr_render_pass *wlr_pass,
|
static void render_pass_add_rect(struct wlr_render_pass *wlr_pass,
|
||||||
const struct wlr_render_rect_options *options) {
|
const struct wlr_render_rect_options *options) {
|
||||||
struct wlr_gles2_render_pass *pass = get_render_pass(wlr_pass);
|
struct wlr_gles_render_pass *pass = get_render_pass(wlr_pass);
|
||||||
struct wlr_gles2_renderer *renderer = pass->buffer->renderer;
|
struct wlr_gles_renderer *renderer = pass->buffer->renderer;
|
||||||
|
|
||||||
const struct wlr_render_color *color = &options->color;
|
const struct wlr_render_color *color = &options->color;
|
||||||
struct wlr_box box;
|
struct wlr_box box;
|
||||||
wlr_render_rect_options_get_box(options, pass->buffer->buffer, &box);
|
wlr_render_rect_options_get_box(options, pass->buffer->buffer, &box);
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
setup_blending(color->a == 1.0 ? WLR_RENDER_BLEND_MODE_NONE : options->blend_mode);
|
setup_blending(color->a == 1.0 ? WLR_RENDER_BLEND_MODE_NONE : options->blend_mode);
|
||||||
|
|
||||||
glUseProgram(renderer->shaders.quad.program);
|
glUseProgram(renderer->shaders.quad.program);
|
||||||
|
|
@ -272,7 +272,7 @@ static void render_pass_add_rect(struct wlr_render_pass *wlr_pass,
|
||||||
|
|
||||||
render(&box, options->clip, renderer->shaders.quad.pos_attrib);
|
render(&box, options->clip, renderer->shaders.quad.pos_attrib);
|
||||||
|
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_render_pass_impl render_pass_impl = {
|
static const struct wlr_render_pass_impl render_pass_impl = {
|
||||||
|
|
@ -294,10 +294,10 @@ static const char *reset_status_str(GLenum status) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_render_pass *begin_gles2_buffer_pass(struct wlr_gles2_buffer *buffer,
|
struct wlr_gles_render_pass *begin_gles_buffer_pass(struct wlr_gles_buffer *buffer,
|
||||||
struct wlr_egl_context *prev_ctx, struct wlr_gles2_render_timer *timer,
|
struct wlr_egl_context *prev_ctx, struct wlr_gles_render_timer *timer,
|
||||||
struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point) {
|
struct wlr_drm_syncobj_timeline *signal_timeline, uint64_t signal_point) {
|
||||||
struct wlr_gles2_renderer *renderer = buffer->renderer;
|
struct wlr_gles_renderer *renderer = buffer->renderer;
|
||||||
struct wlr_buffer *wlr_buffer = buffer->buffer;
|
struct wlr_buffer *wlr_buffer = buffer->buffer;
|
||||||
|
|
||||||
if (renderer->procs.glGetGraphicsResetStatusKHR) {
|
if (renderer->procs.glGetGraphicsResetStatusKHR) {
|
||||||
|
|
@ -309,12 +309,12 @@ struct wlr_gles2_render_pass *begin_gles2_buffer_pass(struct wlr_gles2_buffer *b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint fbo = gles2_buffer_get_fbo(buffer);
|
GLint fbo = gles_buffer_get_fbo(buffer);
|
||||||
if (!fbo) {
|
if (!fbo) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_render_pass *pass = calloc(1, sizeof(*pass));
|
struct wlr_gles_render_pass *pass = calloc(1, sizeof(*pass));
|
||||||
if (pass == NULL) {
|
if (pass == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -332,13 +332,13 @@ struct wlr_gles2_render_pass *begin_gles2_buffer_pass(struct wlr_gles2_buffer *b
|
||||||
matrix_projection(pass->projection_matrix, wlr_buffer->width, wlr_buffer->height,
|
matrix_projection(pass->projection_matrix, wlr_buffer->width, wlr_buffer->height,
|
||||||
WL_OUTPUT_TRANSFORM_FLIPPED_180);
|
WL_OUTPUT_TRANSFORM_FLIPPED_180);
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
|
||||||
glViewport(0, 0, wlr_buffer->width, wlr_buffer->height);
|
glViewport(0, 0, wlr_buffer->width, wlr_buffer->height);
|
||||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,22 @@
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
#include <wlr/config.h>
|
||||||
|
|
||||||
|
#if WLR_HAS_GLES2_RENDERER
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES2/gl2ext.h>
|
||||||
#include "render/gles2.h"
|
#else
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#include <GLES3/gl3ext.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "render/gles.h"
|
||||||
#include "render/pixel_format.h"
|
#include "render/pixel_format.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The DRM formats are little endian while the GL formats are big endian,
|
* The DRM formats are little endian while the GL formats are big endian,
|
||||||
* so DRM_FORMAT_ARGB8888 is actually compatible with GL_BGRA_EXT.
|
* so DRM_FORMAT_ARGB8888 is actually compatible with GL_BGRA_EXT.
|
||||||
*/
|
*/
|
||||||
static const struct wlr_gles2_pixel_format formats[] = {
|
static const struct wlr_gles_pixel_format formats[] = {
|
||||||
{
|
{
|
||||||
.drm_format = DRM_FORMAT_ARGB8888,
|
.drm_format = DRM_FORMAT_ARGB8888,
|
||||||
.gl_format = GL_BGRA_EXT,
|
.gl_format = GL_BGRA_EXT,
|
||||||
|
|
@ -101,8 +109,8 @@ static const struct wlr_gles2_pixel_format formats[] = {
|
||||||
* Return true if supported for texturing, even if other operations like
|
* Return true if supported for texturing, even if other operations like
|
||||||
* reading aren't supported.
|
* reading aren't supported.
|
||||||
*/
|
*/
|
||||||
bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
bool is_gles_pixel_format_supported(const struct wlr_gles_renderer *renderer,
|
||||||
const struct wlr_gles2_pixel_format *format) {
|
const struct wlr_gles_pixel_format *format) {
|
||||||
if (format->gl_type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT
|
if (format->gl_type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT
|
||||||
&& !renderer->exts.EXT_texture_type_2_10_10_10_REV) {
|
&& !renderer->exts.EXT_texture_type_2_10_10_10_REV) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -124,7 +132,7 @@ bool is_gles2_pixel_format_supported(const struct wlr_gles2_renderer *renderer,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct wlr_gles2_pixel_format *get_gles2_format_from_drm(uint32_t fmt) {
|
const struct wlr_gles_pixel_format *get_gles_format_from_drm(uint32_t fmt) {
|
||||||
for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) {
|
for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) {
|
||||||
if (formats[i].drm_format == fmt) {
|
if (formats[i].drm_format == fmt) {
|
||||||
return &formats[i];
|
return &formats[i];
|
||||||
|
|
@ -133,7 +141,7 @@ const struct wlr_gles2_pixel_format *get_gles2_format_from_drm(uint32_t fmt) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct wlr_gles2_pixel_format *get_gles2_format_from_gl(
|
const struct wlr_gles_pixel_format *get_gles_format_from_gl(
|
||||||
GLint gl_format, GLint gl_type, bool alpha) {
|
GLint gl_format, GLint gl_type, bool alpha) {
|
||||||
for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) {
|
for (size_t i = 0; i < sizeof(formats) / sizeof(*formats); ++i) {
|
||||||
if (formats[i].gl_format != gl_format ||
|
if (formats[i].gl_format != gl_format ||
|
||||||
|
|
@ -150,10 +158,10 @@ const struct wlr_gles2_pixel_format *get_gles2_format_from_gl(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_gles2_shm_formats(const struct wlr_gles2_renderer *renderer,
|
void get_gles_shm_formats(const struct wlr_gles_renderer *renderer,
|
||||||
struct wlr_drm_format_set *out) {
|
struct wlr_drm_format_set *out) {
|
||||||
for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
|
for (size_t i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) {
|
||||||
if (!is_gles2_pixel_format_supported(renderer, &formats[i])) {
|
if (!is_gles_pixel_format_supported(renderer, &formats[i])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
wlr_drm_format_set_add(out, formats[i].drm_format, DRM_FORMAT_MOD_INVALID);
|
wlr_drm_format_set_add(out, formats[i].drm_format, DRM_FORMAT_MOD_INVALID);
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wayland-server-protocol.h>
|
#include <wayland-server-protocol.h>
|
||||||
#include <wayland-util.h>
|
#include <wayland-util.h>
|
||||||
|
#include <wlr/config.h>
|
||||||
#include <wlr/render/egl.h>
|
#include <wlr/render/egl.h>
|
||||||
#include <wlr/render/interface.h>
|
#include <wlr/render/interface.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
|
|
@ -16,54 +17,64 @@
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
#include "render/egl.h"
|
#include "render/egl.h"
|
||||||
#include "render/gles2.h"
|
#include "render/gles.h"
|
||||||
#include "render/pixel_format.h"
|
#include "render/pixel_format.h"
|
||||||
#include "util/time.h"
|
#include "util/time.h"
|
||||||
|
|
||||||
#include "common_vert_src.h"
|
#if WLR_HAS_GLES2_RENDERER
|
||||||
#include "quad_frag_src.h"
|
#include "gles2_common_vert_src.h"
|
||||||
#include "tex_rgba_frag_src.h"
|
#include "gles2_quad_frag_src.h"
|
||||||
#include "tex_rgbx_frag_src.h"
|
#include "gles2_tex_rgba_frag_src.h"
|
||||||
#include "tex_external_frag_src.h"
|
#include "gles2_tex_rgbx_frag_src.h"
|
||||||
|
#include "gles2_tex_external_frag_src.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if WLR_HAS_GLES3_RENDERER
|
||||||
|
#include "gles3_common_vert_src.h"
|
||||||
|
#include "gles3_quad_frag_src.h"
|
||||||
|
#include "gles3_tex_rgba_frag_src.h"
|
||||||
|
#include "gles3_tex_rgbx_frag_src.h"
|
||||||
|
#include "gles3_tex_external_frag_src.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
static const struct wlr_renderer_impl renderer_impl;
|
static const struct wlr_renderer_impl renderer_impl;
|
||||||
static const struct wlr_render_timer_impl render_timer_impl;
|
static const struct wlr_render_timer_impl render_timer_impl;
|
||||||
|
|
||||||
bool wlr_renderer_is_gles2(struct wlr_renderer *wlr_renderer) {
|
bool wlr_renderer_is_gles(struct wlr_renderer *wlr_renderer) {
|
||||||
return wlr_renderer->impl == &renderer_impl;
|
return wlr_renderer->impl == &renderer_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_renderer *gles2_get_renderer(
|
struct wlr_gles_renderer *gles_get_renderer(
|
||||||
struct wlr_renderer *wlr_renderer) {
|
struct wlr_renderer *wlr_renderer) {
|
||||||
assert(wlr_renderer_is_gles2(wlr_renderer));
|
assert(wlr_renderer_is_gles(wlr_renderer));
|
||||||
struct wlr_gles2_renderer *renderer = wl_container_of(wlr_renderer, renderer, wlr_renderer);
|
struct wlr_gles_renderer *renderer = wl_container_of(wlr_renderer, renderer, wlr_renderer);
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_render_timer_is_gles2(struct wlr_render_timer *timer) {
|
bool wlr_render_timer_is_gles(struct wlr_render_timer *timer) {
|
||||||
return timer->impl == &render_timer_impl;
|
return timer->impl == &render_timer_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_render_timer *gles2_get_render_timer(struct wlr_render_timer *wlr_timer) {
|
struct wlr_gles_render_timer *gles_get_render_timer(struct wlr_render_timer *wlr_timer) {
|
||||||
assert(wlr_render_timer_is_gles2(wlr_timer));
|
assert(wlr_render_timer_is_gles(wlr_timer));
|
||||||
struct wlr_gles2_render_timer *timer = wl_container_of(wlr_timer, timer, base);
|
struct wlr_gles_render_timer *timer = wl_container_of(wlr_timer, timer, base);
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_buffer(struct wlr_gles2_buffer *buffer) {
|
static void destroy_buffer(struct wlr_gles_buffer *buffer) {
|
||||||
wl_list_remove(&buffer->link);
|
wl_list_remove(&buffer->link);
|
||||||
wlr_addon_finish(&buffer->addon);
|
wlr_addon_finish(&buffer->addon);
|
||||||
|
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
wlr_egl_make_current(buffer->renderer->egl, &prev_ctx);
|
wlr_egl_make_current(buffer->renderer->egl, &prev_ctx);
|
||||||
|
|
||||||
push_gles2_debug(buffer->renderer);
|
push_gles_debug(buffer->renderer);
|
||||||
|
|
||||||
glDeleteFramebuffers(1, &buffer->fbo);
|
glDeleteFramebuffers(1, &buffer->fbo);
|
||||||
glDeleteRenderbuffers(1, &buffer->rbo);
|
glDeleteRenderbuffers(1, &buffer->rbo);
|
||||||
glDeleteTextures(1, &buffer->tex);
|
glDeleteTextures(1, &buffer->tex);
|
||||||
|
|
||||||
pop_gles2_debug(buffer->renderer);
|
pop_gles_debug(buffer->renderer);
|
||||||
|
|
||||||
wlr_egl_destroy_image(buffer->renderer->egl, buffer->image);
|
wlr_egl_destroy_image(buffer->renderer->egl, buffer->image);
|
||||||
|
|
||||||
|
|
@ -73,17 +84,17 @@ static void destroy_buffer(struct wlr_gles2_buffer *buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_buffer_destroy(struct wlr_addon *addon) {
|
static void handle_buffer_destroy(struct wlr_addon *addon) {
|
||||||
struct wlr_gles2_buffer *buffer =
|
struct wlr_gles_buffer *buffer =
|
||||||
wl_container_of(addon, buffer, addon);
|
wl_container_of(addon, buffer, addon);
|
||||||
destroy_buffer(buffer);
|
destroy_buffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_addon_interface buffer_addon_impl = {
|
static const struct wlr_addon_interface buffer_addon_impl = {
|
||||||
.name = "wlr_gles2_buffer",
|
.name = "wlr_gles_buffer",
|
||||||
.destroy = handle_buffer_destroy,
|
.destroy = handle_buffer_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
GLuint gles2_buffer_get_fbo(struct wlr_gles2_buffer *buffer) {
|
GLuint gles_buffer_get_fbo(struct wlr_gles_buffer *buffer) {
|
||||||
if (buffer->external_only) {
|
if (buffer->external_only) {
|
||||||
wlr_log(WLR_ERROR, "DMA-BUF format is external-only");
|
wlr_log(WLR_ERROR, "DMA-BUF format is external-only");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -93,7 +104,7 @@ GLuint gles2_buffer_get_fbo(struct wlr_gles2_buffer *buffer) {
|
||||||
return buffer->fbo;
|
return buffer->fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
push_gles2_debug(buffer->renderer);
|
push_gles_debug(buffer->renderer);
|
||||||
|
|
||||||
if (!buffer->rbo) {
|
if (!buffer->rbo) {
|
||||||
glGenRenderbuffers(1, &buffer->rbo);
|
glGenRenderbuffers(1, &buffer->rbo);
|
||||||
|
|
@ -116,21 +127,21 @@ GLuint gles2_buffer_get_fbo(struct wlr_gles2_buffer *buffer) {
|
||||||
buffer->fbo = 0;
|
buffer->fbo = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_gles2_debug(buffer->renderer);
|
pop_gles_debug(buffer->renderer);
|
||||||
|
|
||||||
return buffer->fbo;
|
return buffer->fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_buffer *gles2_buffer_get_or_create(struct wlr_gles2_renderer *renderer,
|
struct wlr_gles_buffer *gles_buffer_get_or_create(struct wlr_gles_renderer *renderer,
|
||||||
struct wlr_buffer *wlr_buffer) {
|
struct wlr_buffer *wlr_buffer) {
|
||||||
struct wlr_addon *addon =
|
struct wlr_addon *addon =
|
||||||
wlr_addon_find(&wlr_buffer->addons, renderer, &buffer_addon_impl);
|
wlr_addon_find(&wlr_buffer->addons, renderer, &buffer_addon_impl);
|
||||||
if (addon) {
|
if (addon) {
|
||||||
struct wlr_gles2_buffer *buffer = wl_container_of(addon, buffer, addon);
|
struct wlr_gles_buffer *buffer = wl_container_of(addon, buffer, addon);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_buffer *buffer = calloc(1, sizeof(*buffer));
|
struct wlr_gles_buffer *buffer = calloc(1, sizeof(*buffer));
|
||||||
if (buffer == NULL) {
|
if (buffer == NULL) {
|
||||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -164,9 +175,9 @@ error_buffer:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_drm_format_set *gles2_get_texture_formats(
|
static const struct wlr_drm_format_set *gles_get_texture_formats(
|
||||||
struct wlr_renderer *wlr_renderer, uint32_t buffer_caps) {
|
struct wlr_renderer *wlr_renderer, uint32_t buffer_caps) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
if (buffer_caps & WLR_BUFFER_CAP_DMABUF) {
|
if (buffer_caps & WLR_BUFFER_CAP_DMABUF) {
|
||||||
return wlr_egl_get_dmabuf_texture_formats(renderer->egl);
|
return wlr_egl_get_dmabuf_texture_formats(renderer->egl);
|
||||||
} else if (buffer_caps & WLR_BUFFER_CAP_DATA_PTR) {
|
} else if (buffer_caps & WLR_BUFFER_CAP_DATA_PTR) {
|
||||||
|
|
@ -176,15 +187,15 @@ static const struct wlr_drm_format_set *gles2_get_texture_formats(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_drm_format_set *gles2_get_render_formats(
|
static const struct wlr_drm_format_set *gles_get_render_formats(
|
||||||
struct wlr_renderer *wlr_renderer) {
|
struct wlr_renderer *wlr_renderer) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
return wlr_egl_get_dmabuf_render_formats(renderer->egl);
|
return wlr_egl_get_dmabuf_render_formats(renderer->egl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gles2_get_drm_fd(struct wlr_renderer *wlr_renderer) {
|
static int gles_get_drm_fd(struct wlr_renderer *wlr_renderer) {
|
||||||
struct wlr_gles2_renderer *renderer =
|
struct wlr_gles_renderer *renderer =
|
||||||
gles2_get_renderer(wlr_renderer);
|
gles_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
if (renderer->drm_fd < 0) {
|
if (renderer->drm_fd < 0) {
|
||||||
renderer->drm_fd = wlr_egl_dup_drm_fd(renderer->egl);
|
renderer->drm_fd = wlr_egl_dup_drm_fd(renderer->egl);
|
||||||
|
|
@ -193,33 +204,33 @@ static int gles2_get_drm_fd(struct wlr_renderer *wlr_renderer) {
|
||||||
return renderer->drm_fd;
|
return renderer->drm_fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_egl *wlr_gles2_renderer_get_egl(struct wlr_renderer *wlr_renderer) {
|
struct wlr_egl *wlr_gles_renderer_get_egl(struct wlr_renderer *wlr_renderer) {
|
||||||
struct wlr_gles2_renderer *renderer =
|
struct wlr_gles_renderer *renderer =
|
||||||
gles2_get_renderer(wlr_renderer);
|
gles_get_renderer(wlr_renderer);
|
||||||
return renderer->egl;
|
return renderer->egl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gles2_destroy(struct wlr_renderer *wlr_renderer) {
|
static void gles_destroy(struct wlr_renderer *wlr_renderer) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
wlr_egl_make_current(renderer->egl, NULL);
|
wlr_egl_make_current(renderer->egl, NULL);
|
||||||
|
|
||||||
struct wlr_gles2_texture *tex, *tex_tmp;
|
struct wlr_gles_texture *tex, *tex_tmp;
|
||||||
wl_list_for_each_safe(tex, tex_tmp, &renderer->textures, link) {
|
wl_list_for_each_safe(tex, tex_tmp, &renderer->textures, link) {
|
||||||
gles2_texture_destroy(tex);
|
gles_texture_destroy(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_buffer *buffer, *buffer_tmp;
|
struct wlr_gles_buffer *buffer, *buffer_tmp;
|
||||||
wl_list_for_each_safe(buffer, buffer_tmp, &renderer->buffers, link) {
|
wl_list_for_each_safe(buffer, buffer_tmp, &renderer->buffers, link) {
|
||||||
destroy_buffer(buffer);
|
destroy_buffer(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
glDeleteProgram(renderer->shaders.quad.program);
|
glDeleteProgram(renderer->shaders.quad.program);
|
||||||
glDeleteProgram(renderer->shaders.tex_rgba.program);
|
glDeleteProgram(renderer->shaders.tex_rgba.program);
|
||||||
glDeleteProgram(renderer->shaders.tex_rgbx.program);
|
glDeleteProgram(renderer->shaders.tex_rgbx.program);
|
||||||
glDeleteProgram(renderer->shaders.tex_ext.program);
|
glDeleteProgram(renderer->shaders.tex_ext.program);
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
|
|
||||||
if (renderer->exts.KHR_debug) {
|
if (renderer->exts.KHR_debug) {
|
||||||
glDisable(GL_DEBUG_OUTPUT_KHR);
|
glDisable(GL_DEBUG_OUTPUT_KHR);
|
||||||
|
|
@ -238,27 +249,27 @@ static void gles2_destroy(struct wlr_renderer *wlr_renderer) {
|
||||||
free(renderer);
|
free(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_render_pass *gles2_begin_buffer_pass(struct wlr_renderer *wlr_renderer,
|
static struct wlr_render_pass *gles_begin_buffer_pass(struct wlr_renderer *wlr_renderer,
|
||||||
struct wlr_buffer *wlr_buffer, const struct wlr_buffer_pass_options *options) {
|
struct wlr_buffer *wlr_buffer, const struct wlr_buffer_pass_options *options) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
struct wlr_egl_context prev_ctx = {0};
|
struct wlr_egl_context prev_ctx = {0};
|
||||||
if (!wlr_egl_make_current(renderer->egl, &prev_ctx)) {
|
if (!wlr_egl_make_current(renderer->egl, &prev_ctx)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_render_timer *timer = NULL;
|
struct wlr_gles_render_timer *timer = NULL;
|
||||||
if (options->timer) {
|
if (options->timer) {
|
||||||
timer = gles2_get_render_timer(options->timer);
|
timer = gles_get_render_timer(options->timer);
|
||||||
clock_gettime(CLOCK_MONOTONIC, &timer->cpu_start);
|
clock_gettime(CLOCK_MONOTONIC, &timer->cpu_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_buffer *buffer = gles2_buffer_get_or_create(renderer, wlr_buffer);
|
struct wlr_gles_buffer *buffer = gles_buffer_get_or_create(renderer, wlr_buffer);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_render_pass *pass = begin_gles2_buffer_pass(buffer,
|
struct wlr_gles_render_pass *pass = begin_gles_buffer_pass(buffer,
|
||||||
&prev_ctx, timer, options->signal_timeline, options->signal_point);
|
&prev_ctx, timer, options->signal_timeline, options->signal_point);
|
||||||
if (!pass) {
|
if (!pass) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -266,9 +277,9 @@ static struct wlr_render_pass *gles2_begin_buffer_pass(struct wlr_renderer *wlr_
|
||||||
return &pass->base;
|
return &pass->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint wlr_gles2_renderer_get_buffer_fbo(struct wlr_renderer *wlr_renderer,
|
GLuint wlr_gles_renderer_get_buffer_fbo(struct wlr_renderer *wlr_renderer,
|
||||||
struct wlr_buffer *wlr_buffer) {
|
struct wlr_buffer *wlr_buffer) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
GLuint fbo = 0;
|
GLuint fbo = 0;
|
||||||
|
|
||||||
struct wlr_egl_context prev_ctx = {0};
|
struct wlr_egl_context prev_ctx = {0};
|
||||||
|
|
@ -276,23 +287,23 @@ GLuint wlr_gles2_renderer_get_buffer_fbo(struct wlr_renderer *wlr_renderer,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_buffer *buffer = gles2_buffer_get_or_create(renderer, wlr_buffer);
|
struct wlr_gles_buffer *buffer = gles_buffer_get_or_create(renderer, wlr_buffer);
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
fbo = gles2_buffer_get_fbo(buffer);
|
fbo = gles_buffer_get_fbo(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_egl_restore_context(&prev_ctx);
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
return fbo;
|
return fbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_render_timer *gles2_render_timer_create(struct wlr_renderer *wlr_renderer) {
|
static struct wlr_render_timer *gles_render_timer_create(struct wlr_renderer *wlr_renderer) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
if (!renderer->exts.EXT_disjoint_timer_query) {
|
if (!renderer->exts.EXT_disjoint_timer_query) {
|
||||||
wlr_log(WLR_ERROR, "can't create timer, EXT_disjoint_timer_query not available");
|
wlr_log(WLR_ERROR, "can't create timer, EXT_disjoint_timer_query not available");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_render_timer *timer = calloc(1, sizeof(*timer));
|
struct wlr_gles_render_timer *timer = calloc(1, sizeof(*timer));
|
||||||
if (!timer) {
|
if (!timer) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -307,9 +318,9 @@ static struct wlr_render_timer *gles2_render_timer_create(struct wlr_renderer *w
|
||||||
return &timer->base;
|
return &timer->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gles2_get_render_time(struct wlr_render_timer *wlr_timer) {
|
static int gles_get_render_time(struct wlr_render_timer *wlr_timer) {
|
||||||
struct wlr_gles2_render_timer *timer = gles2_get_render_timer(wlr_timer);
|
struct wlr_gles_render_timer *timer = gles_get_render_timer(wlr_timer);
|
||||||
struct wlr_gles2_renderer *renderer = timer->renderer;
|
struct wlr_gles_renderer *renderer = timer->renderer;
|
||||||
|
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
||||||
|
|
@ -341,9 +352,9 @@ static int gles2_get_render_time(struct wlr_render_timer *wlr_timer) {
|
||||||
return gl_render_end - timer->gl_cpu_end + cpu_nsec_total;
|
return gl_render_end - timer->gl_cpu_end + cpu_nsec_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gles2_render_timer_destroy(struct wlr_render_timer *wlr_timer) {
|
static void gles_render_timer_destroy(struct wlr_render_timer *wlr_timer) {
|
||||||
struct wlr_gles2_render_timer *timer = wl_container_of(wlr_timer, timer, base);
|
struct wlr_gles_render_timer *timer = wl_container_of(wlr_timer, timer, base);
|
||||||
struct wlr_gles2_renderer *renderer = timer->renderer;
|
struct wlr_gles_renderer *renderer = timer->renderer;
|
||||||
|
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
||||||
|
|
@ -353,21 +364,21 @@ static void gles2_render_timer_destroy(struct wlr_render_timer *wlr_timer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_renderer_impl renderer_impl = {
|
static const struct wlr_renderer_impl renderer_impl = {
|
||||||
.destroy = gles2_destroy,
|
.destroy = gles_destroy,
|
||||||
.get_texture_formats = gles2_get_texture_formats,
|
.get_texture_formats = gles_get_texture_formats,
|
||||||
.get_render_formats = gles2_get_render_formats,
|
.get_render_formats = gles_get_render_formats,
|
||||||
.get_drm_fd = gles2_get_drm_fd,
|
.get_drm_fd = gles_get_drm_fd,
|
||||||
.texture_from_buffer = gles2_texture_from_buffer,
|
.texture_from_buffer = gles_texture_from_buffer,
|
||||||
.begin_buffer_pass = gles2_begin_buffer_pass,
|
.begin_buffer_pass = gles_begin_buffer_pass,
|
||||||
.render_timer_create = gles2_render_timer_create,
|
.render_timer_create = gles_render_timer_create,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wlr_render_timer_impl render_timer_impl = {
|
static const struct wlr_render_timer_impl render_timer_impl = {
|
||||||
.get_duration_ns = gles2_get_render_time,
|
.get_duration_ns = gles_get_render_time,
|
||||||
.destroy = gles2_render_timer_destroy,
|
.destroy = gles_render_timer_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
void push_gles2_debug_(struct wlr_gles2_renderer *renderer,
|
void push_gles_debug_(struct wlr_gles_renderer *renderer,
|
||||||
const char *file, const char *func) {
|
const char *file, const char *func) {
|
||||||
if (!renderer->procs.glPushDebugGroupKHR) {
|
if (!renderer->procs.glPushDebugGroupKHR) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -379,13 +390,13 @@ void push_gles2_debug_(struct wlr_gles2_renderer *renderer,
|
||||||
renderer->procs.glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 1, -1, str);
|
renderer->procs.glPushDebugGroupKHR(GL_DEBUG_SOURCE_APPLICATION_KHR, 1, -1, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pop_gles2_debug(struct wlr_gles2_renderer *renderer) {
|
void pop_gles_debug(struct wlr_gles_renderer *renderer) {
|
||||||
if (renderer->procs.glPopDebugGroupKHR) {
|
if (renderer->procs.glPopDebugGroupKHR) {
|
||||||
renderer->procs.glPopDebugGroupKHR();
|
renderer->procs.glPopDebugGroupKHR();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum wlr_log_importance gles2_log_importance_to_wlr(GLenum type) {
|
static enum wlr_log_importance gles_log_importance_to_wlr(GLenum type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case GL_DEBUG_TYPE_ERROR_KHR: return WLR_ERROR;
|
case GL_DEBUG_TYPE_ERROR_KHR: return WLR_ERROR;
|
||||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR: return WLR_DEBUG;
|
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR: return WLR_DEBUG;
|
||||||
|
|
@ -400,14 +411,14 @@ static enum wlr_log_importance gles2_log_importance_to_wlr(GLenum type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gles2_log(GLenum src, GLenum type, GLuint id, GLenum severity,
|
static void gles_log(GLenum src, GLenum type, GLuint id, GLenum severity,
|
||||||
GLsizei len, const GLchar *msg, const void *user) {
|
GLsizei len, const GLchar *msg, const void *user) {
|
||||||
_wlr_log(gles2_log_importance_to_wlr(type), "[GLES2] %s", msg);
|
_wlr_log(gles_log_importance_to_wlr(type), "[GLES] %s", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint compile_shader(struct wlr_gles2_renderer *renderer,
|
static GLuint compile_shader(struct wlr_gles_renderer *renderer,
|
||||||
GLenum type, const GLchar *src) {
|
GLenum type, const GLchar *src) {
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
|
|
||||||
GLuint shader = glCreateShader(type);
|
GLuint shader = glCreateShader(type);
|
||||||
glShaderSource(shader, 1, &src, NULL);
|
glShaderSource(shader, 1, &src, NULL);
|
||||||
|
|
@ -421,13 +432,13 @@ static GLuint compile_shader(struct wlr_gles2_renderer *renderer,
|
||||||
shader = 0;
|
shader = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
return shader;
|
return shader;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint link_program(struct wlr_gles2_renderer *renderer,
|
static GLuint link_program(struct wlr_gles_renderer *renderer,
|
||||||
const GLchar *vert_src, const GLchar *frag_src) {
|
const GLchar *vert_src, const GLchar *frag_src) {
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
|
|
||||||
GLuint vert = compile_shader(renderer, GL_VERTEX_SHADER, vert_src);
|
GLuint vert = compile_shader(renderer, GL_VERTEX_SHADER, vert_src);
|
||||||
if (!vert) {
|
if (!vert) {
|
||||||
|
|
@ -458,11 +469,11 @@ static GLuint link_program(struct wlr_gles2_renderer *renderer,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
return prog;
|
return prog;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -493,16 +504,17 @@ static void load_gl_proc(void *proc_ptr, const char *name) {
|
||||||
*(void **)proc_ptr = proc;
|
*(void **)proc_ptr = proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_renderer *wlr_gles2_renderer_create_with_drm_fd(int drm_fd) {
|
struct wlr_renderer *wlr_gles_renderer_create_with_drm_fd(int drm_fd,
|
||||||
struct wlr_egl *egl = wlr_egl_create_with_drm_fd(drm_fd);
|
enum egl_version version) {
|
||||||
|
struct wlr_egl *egl = wlr_egl_create_with_drm_fd(drm_fd, version);
|
||||||
if (egl == NULL) {
|
if (egl == NULL) {
|
||||||
wlr_log(WLR_ERROR, "Could not initialize EGL");
|
wlr_log(WLR_ERROR, "Could not initialize EGL");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_renderer *renderer = wlr_gles2_renderer_create(egl);
|
struct wlr_renderer *renderer = wlr_gles_renderer_create(egl);
|
||||||
if (!renderer) {
|
if (!renderer) {
|
||||||
wlr_log(WLR_ERROR, "Failed to create GLES2 renderer");
|
wlr_log(WLR_ERROR, "Failed to create GLES renderer");
|
||||||
wlr_egl_destroy(egl);
|
wlr_egl_destroy(egl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -510,7 +522,7 @@ struct wlr_renderer *wlr_gles2_renderer_create_with_drm_fd(int drm_fd) {
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
struct wlr_renderer *wlr_gles_renderer_create(struct wlr_egl *egl) {
|
||||||
if (!wlr_egl_make_current(egl, NULL)) {
|
if (!wlr_egl_make_current(egl, NULL)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -521,7 +533,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_renderer *renderer = calloc(1, sizeof(*renderer));
|
struct wlr_gles_renderer *renderer = calloc(1, sizeof(*renderer));
|
||||||
if (renderer == NULL) {
|
if (renderer == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -535,11 +547,11 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
renderer->exts_str = exts_str;
|
renderer->exts_str = exts_str;
|
||||||
renderer->drm_fd = -1;
|
renderer->drm_fd = -1;
|
||||||
|
|
||||||
wlr_log(WLR_INFO, "Creating GLES2 renderer");
|
wlr_log(WLR_INFO, "Creating GLES renderer");
|
||||||
wlr_log(WLR_INFO, "Using %s", glGetString(GL_VERSION));
|
wlr_log(WLR_INFO, "Using %s", glGetString(GL_VERSION));
|
||||||
wlr_log(WLR_INFO, "GL vendor: %s", glGetString(GL_VENDOR));
|
wlr_log(WLR_INFO, "GL vendor: %s", glGetString(GL_VENDOR));
|
||||||
wlr_log(WLR_INFO, "GL renderer: %s", glGetString(GL_RENDERER));
|
wlr_log(WLR_INFO, "GL renderer: %s", glGetString(GL_RENDERER));
|
||||||
wlr_log(WLR_INFO, "Supported GLES2 extensions: %s", exts_str);
|
wlr_log(WLR_INFO, "Supported GLES extensions: %s", exts_str);
|
||||||
|
|
||||||
if (!renderer->egl->exts.EXT_image_dma_buf_import) {
|
if (!renderer->egl->exts.EXT_image_dma_buf_import) {
|
||||||
wlr_log(WLR_ERROR, "EGL_EXT_image_dma_buf_import not supported");
|
wlr_log(WLR_ERROR, "EGL_EXT_image_dma_buf_import not supported");
|
||||||
|
|
@ -547,7 +559,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!check_gl_ext(exts_str, "GL_EXT_texture_format_BGRA8888")) {
|
if (!check_gl_ext(exts_str, "GL_EXT_texture_format_BGRA8888")) {
|
||||||
wlr_log(WLR_ERROR, "BGRA8888 format not supported by GLES2");
|
wlr_log(WLR_ERROR, "BGRA8888 format not supported by GLES");
|
||||||
free(renderer);
|
free(renderer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -621,7 +633,7 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
if (renderer->exts.KHR_debug) {
|
if (renderer->exts.KHR_debug) {
|
||||||
glEnable(GL_DEBUG_OUTPUT_KHR);
|
glEnable(GL_DEBUG_OUTPUT_KHR);
|
||||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR);
|
||||||
renderer->procs.glDebugMessageCallbackKHR(gles2_log, NULL);
|
renderer->procs.glDebugMessageCallbackKHR(gles_log, NULL);
|
||||||
|
|
||||||
// Silence unwanted message types
|
// Silence unwanted message types
|
||||||
renderer->procs.glDebugMessageControlKHR(GL_DONT_CARE,
|
renderer->procs.glDebugMessageControlKHR(GL_DONT_CARE,
|
||||||
|
|
@ -630,7 +642,31 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
GL_DEBUG_TYPE_PUSH_GROUP_KHR, GL_DONT_CARE, 0, NULL, GL_FALSE);
|
GL_DEBUG_TYPE_PUSH_GROUP_KHR, GL_DONT_CARE, 0, NULL, GL_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
|
|
||||||
|
const char* common_vert_src;
|
||||||
|
const char* quad_frag_src;
|
||||||
|
const char* tex_rgba_frag_src;
|
||||||
|
const char* tex_rgbx_frag_src;
|
||||||
|
const char* tex_external_frag_src;
|
||||||
|
|
||||||
|
if (egl->version == GLES2) {
|
||||||
|
#if WLR_HAS_GLES2_RENDERER
|
||||||
|
common_vert_src = gles2_common_vert_src;
|
||||||
|
quad_frag_src = gles2_quad_frag_src;
|
||||||
|
tex_rgba_frag_src = gles2_tex_rgba_frag_src;
|
||||||
|
tex_rgbx_frag_src = gles2_tex_rgbx_frag_src;
|
||||||
|
tex_external_frag_src = gles2_tex_external_frag_src;
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#if WLR_HAS_GLES3_RENDERER
|
||||||
|
common_vert_src = gles3_common_vert_src;
|
||||||
|
quad_frag_src = gles3_quad_frag_src;
|
||||||
|
tex_rgba_frag_src = gles3_tex_rgba_frag_src;
|
||||||
|
tex_rgbx_frag_src = gles3_tex_rgbx_frag_src;
|
||||||
|
tex_external_frag_src = gles3_tex_external_frag_src;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
GLuint prog;
|
GLuint prog;
|
||||||
renderer->shaders.quad.program = prog =
|
renderer->shaders.quad.program = prog =
|
||||||
|
|
@ -677,11 +713,11 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
|
||||||
renderer->shaders.tex_ext.pos_attrib = glGetAttribLocation(prog, "pos");
|
renderer->shaders.tex_ext.pos_attrib = glGetAttribLocation(prog, "pos");
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
|
|
||||||
wlr_egl_unset_current(renderer->egl);
|
wlr_egl_unset_current(renderer->egl);
|
||||||
|
|
||||||
get_gles2_shm_formats(renderer, &renderer->shm_texture_formats);
|
get_gles_shm_formats(renderer, &renderer->shm_texture_formats);
|
||||||
|
|
||||||
int drm_fd = wlr_renderer_get_drm_fd(&renderer->wlr_renderer);
|
int drm_fd = wlr_renderer_get_drm_fd(&renderer->wlr_renderer);
|
||||||
uint64_t cap_syncobj_timeline;
|
uint64_t cap_syncobj_timeline;
|
||||||
|
|
@ -698,7 +734,7 @@ error:
|
||||||
glDeleteProgram(renderer->shaders.tex_rgbx.program);
|
glDeleteProgram(renderer->shaders.tex_rgbx.program);
|
||||||
glDeleteProgram(renderer->shaders.tex_ext.program);
|
glDeleteProgram(renderer->shaders.tex_ext.program);
|
||||||
|
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
|
|
||||||
if (renderer->exts.KHR_debug) {
|
if (renderer->exts.KHR_debug) {
|
||||||
glDisable(GL_DEBUG_OUTPUT_KHR);
|
glDisable(GL_DEBUG_OUTPUT_KHR);
|
||||||
|
|
@ -711,8 +747,8 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wlr_gles2_renderer_check_ext(struct wlr_renderer *wlr_renderer,
|
bool wlr_gles_renderer_check_ext(struct wlr_renderer *wlr_renderer,
|
||||||
const char *ext) {
|
const char *ext) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
return check_gl_ext(renderer->exts_str, ext);
|
return check_gl_ext(renderer->exts_str, ext);
|
||||||
}
|
}
|
||||||
12
render/gles/shaders/gles3_common.vert
Normal file
12
render/gles/shaders/gles3_common.vert
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
uniform mat3 proj;
|
||||||
|
uniform mat3 tex_proj;
|
||||||
|
in vec2 pos;
|
||||||
|
out vec2 v_texcoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 pos3 = vec3(pos, 1.0);
|
||||||
|
gl_Position = vec4(pos3 * proj, 1.0);
|
||||||
|
v_texcoord = (pos3 * tex_proj).xy;
|
||||||
|
}
|
||||||
13
render/gles/shaders/gles3_quad.frag
Normal file
13
render/gles/shaders/gles3_quad.frag
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in vec4 v_color;
|
||||||
|
in vec2 v_texcoord;
|
||||||
|
uniform vec4 color;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = color;
|
||||||
|
}
|
||||||
15
render/gles/shaders/gles3_tex_external.frag
Normal file
15
render/gles/shaders/gles3_tex_external.frag
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
#extension GL_OES_EGL_image_external_essl3 : require
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in vec2 v_texcoord;
|
||||||
|
uniform samplerExternalOES texture0;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = texture(texture0, v_texcoord) * alpha;
|
||||||
|
}
|
||||||
13
render/gles/shaders/gles3_tex_rgba.frag
Normal file
13
render/gles/shaders/gles3_tex_rgba.frag
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in vec2 v_texcoord;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = texture(tex, v_texcoord) * alpha;
|
||||||
|
}
|
||||||
13
render/gles/shaders/gles3_tex_rgbx.frag
Normal file
13
render/gles/shaders/gles3_tex_rgbx.frag
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
#version 300 es
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
in vec2 v_texcoord;
|
||||||
|
uniform sampler2D tex;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
out vec4 frag_color;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
frag_color = vec4(texture(tex, v_texcoord).rgb, 1.0) * alpha;
|
||||||
|
}
|
||||||
|
|
@ -1,16 +1,21 @@
|
||||||
embed = find_program('./embed.sh', native: true)
|
embed = find_program('./embed.sh', native: true)
|
||||||
|
|
||||||
shaders = [
|
shaders = [
|
||||||
'common.vert',
|
'gles2_common.vert',
|
||||||
'quad.frag',
|
'gles2_quad.frag',
|
||||||
'tex_rgba.frag',
|
'gles2_tex_rgba.frag',
|
||||||
'tex_rgbx.frag',
|
'gles2_tex_rgbx.frag',
|
||||||
'tex_external.frag',
|
'gles2_tex_external.frag',
|
||||||
|
'gles3_common.vert',
|
||||||
|
'gles3_quad.frag',
|
||||||
|
'gles3_tex_rgba.frag',
|
||||||
|
'gles3_tex_rgbx.frag',
|
||||||
|
'gles3_tex_external.frag',
|
||||||
]
|
]
|
||||||
|
|
||||||
foreach name : shaders
|
foreach name : shaders
|
||||||
custom_target(
|
custom_target(
|
||||||
'gles2-' + name,
|
'gles-' + name,
|
||||||
input: name,
|
input: name,
|
||||||
output: name + '_check',
|
output: name + '_check',
|
||||||
command: [glslang, '@INPUT@'],
|
command: [glslang, '@INPUT@'],
|
||||||
|
|
@ -1,7 +1,16 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <drm_fourcc.h>
|
#include <drm_fourcc.h>
|
||||||
|
|
||||||
|
#include <wlr/config.h>
|
||||||
|
|
||||||
|
#if WLR_HAS_GLES2_RENDERER
|
||||||
#include <GLES2/gl2.h>
|
#include <GLES2/gl2.h>
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES2/gl2ext.h>
|
||||||
|
#else
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#include <GLES3/gl3ext.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <wayland-server-protocol.h>
|
#include <wayland-server-protocol.h>
|
||||||
|
|
@ -11,25 +20,25 @@
|
||||||
#include <wlr/render/wlr_texture.h>
|
#include <wlr/render/wlr_texture.h>
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include "render/egl.h"
|
#include "render/egl.h"
|
||||||
#include "render/gles2.h"
|
#include "render/gles.h"
|
||||||
#include "render/pixel_format.h"
|
#include "render/pixel_format.h"
|
||||||
|
|
||||||
static const struct wlr_texture_impl texture_impl;
|
static const struct wlr_texture_impl texture_impl;
|
||||||
|
|
||||||
bool wlr_texture_is_gles2(struct wlr_texture *wlr_texture) {
|
bool wlr_texture_is_gles(struct wlr_texture *wlr_texture) {
|
||||||
return wlr_texture->impl == &texture_impl;
|
return wlr_texture->impl == &texture_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_texture *gles2_get_texture(
|
struct wlr_gles_texture *gles_get_texture(
|
||||||
struct wlr_texture *wlr_texture) {
|
struct wlr_texture *wlr_texture) {
|
||||||
assert(wlr_texture_is_gles2(wlr_texture));
|
assert(wlr_texture_is_gles(wlr_texture));
|
||||||
struct wlr_gles2_texture *texture = wl_container_of(wlr_texture, texture, wlr_texture);
|
struct wlr_gles_texture *texture = wl_container_of(wlr_texture, texture, wlr_texture);
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gles2_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
static bool gles_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
||||||
struct wlr_buffer *buffer, const pixman_region32_t *damage) {
|
struct wlr_buffer *buffer, const pixman_region32_t *damage) {
|
||||||
struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
|
struct wlr_gles_texture *texture = gles_get_texture(wlr_texture);
|
||||||
|
|
||||||
if (texture->drm_format == DRM_FORMAT_INVALID) {
|
if (texture->drm_format == DRM_FORMAT_INVALID) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -48,8 +57,8 @@ static bool gles2_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct wlr_gles2_pixel_format *fmt =
|
const struct wlr_gles_pixel_format *fmt =
|
||||||
get_gles2_format_from_drm(texture->drm_format);
|
get_gles_format_from_drm(texture->drm_format);
|
||||||
assert(fmt);
|
assert(fmt);
|
||||||
|
|
||||||
const struct wlr_pixel_format_info *drm_fmt =
|
const struct wlr_pixel_format_info *drm_fmt =
|
||||||
|
|
@ -69,7 +78,7 @@ static bool gles2_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
wlr_egl_make_current(texture->renderer->egl, &prev_ctx);
|
wlr_egl_make_current(texture->renderer->egl, &prev_ctx);
|
||||||
|
|
||||||
push_gles2_debug(texture->renderer);
|
push_gles_debug(texture->renderer);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->tex);
|
glBindTexture(GL_TEXTURE_2D, texture->tex);
|
||||||
|
|
||||||
|
|
@ -95,7 +104,7 @@ static bool gles2_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
pop_gles2_debug(texture->renderer);
|
pop_gles_debug(texture->renderer);
|
||||||
|
|
||||||
wlr_egl_restore_context(&prev_ctx);
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
|
|
||||||
|
|
@ -104,7 +113,7 @@ static bool gles2_texture_update_from_buffer(struct wlr_texture *wlr_texture,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gles2_texture_destroy(struct wlr_gles2_texture *texture) {
|
void gles_texture_destroy(struct wlr_gles_texture *texture) {
|
||||||
wl_list_remove(&texture->link);
|
wl_list_remove(&texture->link);
|
||||||
if (texture->buffer != NULL) {
|
if (texture->buffer != NULL) {
|
||||||
wlr_buffer_unlock(texture->buffer->buffer);
|
wlr_buffer_unlock(texture->buffer->buffer);
|
||||||
|
|
@ -112,12 +121,12 @@ void gles2_texture_destroy(struct wlr_gles2_texture *texture) {
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
wlr_egl_make_current(texture->renderer->egl, &prev_ctx);
|
wlr_egl_make_current(texture->renderer->egl, &prev_ctx);
|
||||||
|
|
||||||
push_gles2_debug(texture->renderer);
|
push_gles_debug(texture->renderer);
|
||||||
|
|
||||||
glDeleteTextures(1, &texture->tex);
|
glDeleteTextures(1, &texture->tex);
|
||||||
glDeleteFramebuffers(1, &texture->fbo);
|
glDeleteFramebuffers(1, &texture->fbo);
|
||||||
|
|
||||||
pop_gles2_debug(texture->renderer);
|
pop_gles_debug(texture->renderer);
|
||||||
|
|
||||||
wlr_egl_restore_context(&prev_ctx);
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
}
|
}
|
||||||
|
|
@ -125,11 +134,11 @@ void gles2_texture_destroy(struct wlr_gles2_texture *texture) {
|
||||||
free(texture);
|
free(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_gles2_texture_destroy(struct wlr_texture *wlr_texture) {
|
static void handle_gles_texture_destroy(struct wlr_texture *wlr_texture) {
|
||||||
gles2_texture_destroy(gles2_get_texture(wlr_texture));
|
gles_texture_destroy(gles_get_texture(wlr_texture));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gles2_texture_bind(struct wlr_gles2_texture *texture) {
|
static bool gles_texture_bind(struct wlr_gles_texture *texture) {
|
||||||
if (texture->fbo) {
|
if (texture->fbo) {
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, texture->fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, texture->fbo);
|
||||||
} else if (texture->buffer) {
|
} else if (texture->buffer) {
|
||||||
|
|
@ -137,7 +146,7 @@ static bool gles2_texture_bind(struct wlr_gles2_texture *texture) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint fbo = gles2_buffer_get_fbo(texture->buffer);
|
GLuint fbo = gles_buffer_get_fbo(texture->buffer);
|
||||||
if (!fbo) {
|
if (!fbo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -163,16 +172,16 @@ static bool gles2_texture_bind(struct wlr_gles2_texture *texture) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gles2_texture_read_pixels(struct wlr_texture *wlr_texture,
|
static bool gles_texture_read_pixels(struct wlr_texture *wlr_texture,
|
||||||
const struct wlr_texture_read_pixels_options *options) {
|
const struct wlr_texture_read_pixels_options *options) {
|
||||||
struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
|
struct wlr_gles_texture *texture = gles_get_texture(wlr_texture);
|
||||||
|
|
||||||
struct wlr_box src;
|
struct wlr_box src;
|
||||||
wlr_texture_read_pixels_options_get_src_box(options, wlr_texture, &src);
|
wlr_texture_read_pixels_options_get_src_box(options, wlr_texture, &src);
|
||||||
|
|
||||||
const struct wlr_gles2_pixel_format *fmt =
|
const struct wlr_gles_pixel_format *fmt =
|
||||||
get_gles2_format_from_drm(options->format);
|
get_gles_format_from_drm(options->format);
|
||||||
if (fmt == NULL || !is_gles2_pixel_format_supported(texture->renderer, fmt)) {
|
if (fmt == NULL || !is_gles_pixel_format_supported(texture->renderer, fmt)) {
|
||||||
wlr_log(WLR_ERROR, "Cannot read pixels: unsupported pixel format 0x%"PRIX32, options->format);
|
wlr_log(WLR_ERROR, "Cannot read pixels: unsupported pixel format 0x%"PRIX32, options->format);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -191,13 +200,13 @@ static bool gles2_texture_read_pixels(struct wlr_texture *wlr_texture,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
push_gles2_debug(texture->renderer);
|
push_gles_debug(texture->renderer);
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
if (!wlr_egl_make_current(texture->renderer->egl, &prev_ctx)) {
|
if (!wlr_egl_make_current(texture->renderer->egl, &prev_ctx)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gles2_texture_bind(texture)) {
|
if (!gles_texture_bind(texture)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -216,7 +225,7 @@ static bool gles2_texture_read_pixels(struct wlr_texture *wlr_texture,
|
||||||
|
|
||||||
glReadPixels(src.x, src.y, src.width, src.height, fmt->gl_format, fmt->gl_type, p);
|
glReadPixels(src.x, src.y, src.width, src.height, fmt->gl_format, fmt->gl_type, p);
|
||||||
} else {
|
} else {
|
||||||
// Unfortunately GLES2 doesn't support GL_PACK_ROW_LENGTH, so we have to read
|
// Unfortunately GLES doesn't support GL_PACK_ROW_LENGTH, so we have to read
|
||||||
// the lines out row by row
|
// the lines out row by row
|
||||||
for (int32_t i = 0; i < src.height; ++i) {
|
for (int32_t i = 0; i < src.height; ++i) {
|
||||||
uint32_t y = src.y + i;
|
uint32_t y = src.y + i;
|
||||||
|
|
@ -226,15 +235,15 @@ static bool gles2_texture_read_pixels(struct wlr_texture *wlr_texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
wlr_egl_restore_context(&prev_ctx);
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
pop_gles2_debug(texture->renderer);
|
pop_gles_debug(texture->renderer);
|
||||||
|
|
||||||
return glGetError() == GL_NO_ERROR;
|
return glGetError() == GL_NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t gles2_texture_preferred_read_format(struct wlr_texture *wlr_texture) {
|
static uint32_t gles_texture_preferred_read_format(struct wlr_texture *wlr_texture) {
|
||||||
struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
|
struct wlr_gles_texture *texture = gles_get_texture(wlr_texture);
|
||||||
|
|
||||||
push_gles2_debug(texture->renderer);
|
push_gles_debug(texture->renderer);
|
||||||
|
|
||||||
uint32_t fmt = DRM_FORMAT_INVALID;
|
uint32_t fmt = DRM_FORMAT_INVALID;
|
||||||
|
|
||||||
|
|
@ -243,7 +252,7 @@ static uint32_t gles2_texture_preferred_read_format(struct wlr_texture *wlr_text
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gles2_texture_bind(texture)) {
|
if (!gles_texture_bind(texture)) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -253,10 +262,10 @@ static uint32_t gles2_texture_preferred_read_format(struct wlr_texture *wlr_text
|
||||||
glGetIntegerv(GL_ALPHA_BITS, &alpha_size);
|
glGetIntegerv(GL_ALPHA_BITS, &alpha_size);
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
pop_gles2_debug(texture->renderer);
|
pop_gles_debug(texture->renderer);
|
||||||
|
|
||||||
const struct wlr_gles2_pixel_format *pix_fmt =
|
const struct wlr_gles_pixel_format *pix_fmt =
|
||||||
get_gles2_format_from_gl(gl_format, gl_type, alpha_size > 0);
|
get_gles_format_from_gl(gl_format, gl_type, alpha_size > 0);
|
||||||
if (pix_fmt != NULL) {
|
if (pix_fmt != NULL) {
|
||||||
fmt = pix_fmt->drm_format;
|
fmt = pix_fmt->drm_format;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -273,15 +282,15 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wlr_texture_impl texture_impl = {
|
static const struct wlr_texture_impl texture_impl = {
|
||||||
.update_from_buffer = gles2_texture_update_from_buffer,
|
.update_from_buffer = gles_texture_update_from_buffer,
|
||||||
.read_pixels = gles2_texture_read_pixels,
|
.read_pixels = gles_texture_read_pixels,
|
||||||
.preferred_read_format = gles2_texture_preferred_read_format,
|
.preferred_read_format = gles_texture_preferred_read_format,
|
||||||
.destroy = handle_gles2_texture_destroy,
|
.destroy = handle_gles_texture_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct wlr_gles2_texture *gles2_texture_create(
|
static struct wlr_gles_texture *gles_texture_create(
|
||||||
struct wlr_gles2_renderer *renderer, uint32_t width, uint32_t height) {
|
struct wlr_gles_renderer *renderer, uint32_t width, uint32_t height) {
|
||||||
struct wlr_gles2_texture *texture = calloc(1, sizeof(*texture));
|
struct wlr_gles_texture *texture = calloc(1, sizeof(*texture));
|
||||||
if (texture == NULL) {
|
if (texture == NULL) {
|
||||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -293,14 +302,14 @@ static struct wlr_gles2_texture *gles2_texture_create(
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_texture *gles2_texture_from_pixels(
|
static struct wlr_texture *gles_texture_from_pixels(
|
||||||
struct wlr_renderer *wlr_renderer,
|
struct wlr_renderer *wlr_renderer,
|
||||||
uint32_t drm_format, uint32_t stride, uint32_t width,
|
uint32_t drm_format, uint32_t stride, uint32_t width,
|
||||||
uint32_t height, const void *data) {
|
uint32_t height, const void *data) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
const struct wlr_gles2_pixel_format *fmt =
|
const struct wlr_gles_pixel_format *fmt =
|
||||||
get_gles2_format_from_drm(drm_format);
|
get_gles_format_from_drm(drm_format);
|
||||||
if (fmt == NULL) {
|
if (fmt == NULL) {
|
||||||
wlr_log(WLR_ERROR, "Unsupported pixel format 0x%"PRIX32, drm_format);
|
wlr_log(WLR_ERROR, "Unsupported pixel format 0x%"PRIX32, drm_format);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -318,8 +327,8 @@ static struct wlr_texture *gles2_texture_from_pixels(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_texture *texture =
|
struct wlr_gles_texture *texture =
|
||||||
gles2_texture_create(renderer, width, height);
|
gles_texture_create(renderer, width, height);
|
||||||
if (texture == NULL) {
|
if (texture == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -335,7 +344,7 @@ static struct wlr_texture *gles2_texture_from_pixels(
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
||||||
|
|
||||||
push_gles2_debug(renderer);
|
push_gles_debug(renderer);
|
||||||
|
|
||||||
glGenTextures(1, &texture->tex);
|
glGenTextures(1, &texture->tex);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->tex);
|
glBindTexture(GL_TEXTURE_2D, texture->tex);
|
||||||
|
|
@ -349,27 +358,27 @@ static struct wlr_texture *gles2_texture_from_pixels(
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
pop_gles2_debug(renderer);
|
pop_gles_debug(renderer);
|
||||||
|
|
||||||
wlr_egl_restore_context(&prev_ctx);
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
|
|
||||||
return &texture->wlr_texture;
|
return &texture->wlr_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct wlr_texture *gles2_texture_from_dmabuf(
|
static struct wlr_texture *gles_texture_from_dmabuf(
|
||||||
struct wlr_gles2_renderer *renderer, struct wlr_buffer *wlr_buffer,
|
struct wlr_gles_renderer *renderer, struct wlr_buffer *wlr_buffer,
|
||||||
struct wlr_dmabuf_attributes *attribs) {
|
struct wlr_dmabuf_attributes *attribs) {
|
||||||
if (!renderer->procs.glEGLImageTargetTexture2DOES) {
|
if (!renderer->procs.glEGLImageTargetTexture2DOES) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_buffer *buffer = gles2_buffer_get_or_create(renderer, wlr_buffer);
|
struct wlr_gles_buffer *buffer = gles_buffer_get_or_create(renderer, wlr_buffer);
|
||||||
if (!buffer) {
|
if (!buffer) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_gles2_texture *texture =
|
struct wlr_gles_texture *texture =
|
||||||
gles2_texture_create(renderer, attribs->width, attribs->height);
|
gles_texture_create(renderer, attribs->width, attribs->height);
|
||||||
if (texture == NULL) {
|
if (texture == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -381,7 +390,7 @@ static struct wlr_texture *gles2_texture_from_dmabuf(
|
||||||
|
|
||||||
struct wlr_egl_context prev_ctx;
|
struct wlr_egl_context prev_ctx;
|
||||||
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
wlr_egl_make_current(renderer->egl, &prev_ctx);
|
||||||
push_gles2_debug(texture->renderer);
|
push_gles_debug(texture->renderer);
|
||||||
|
|
||||||
bool invalid;
|
bool invalid;
|
||||||
if (!buffer->tex) {
|
if (!buffer->tex) {
|
||||||
|
|
@ -400,7 +409,7 @@ static struct wlr_texture *gles2_texture_from_dmabuf(
|
||||||
glBindTexture(texture->target, 0);
|
glBindTexture(texture->target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
pop_gles2_debug(texture->renderer);
|
pop_gles_debug(texture->renderer);
|
||||||
wlr_egl_restore_context(&prev_ctx);
|
wlr_egl_restore_context(&prev_ctx);
|
||||||
|
|
||||||
texture->tex = buffer->tex;
|
texture->tex = buffer->tex;
|
||||||
|
|
@ -408,19 +417,19 @@ static struct wlr_texture *gles2_texture_from_dmabuf(
|
||||||
return &texture->wlr_texture;
|
return &texture->wlr_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_texture *gles2_texture_from_buffer(struct wlr_renderer *wlr_renderer,
|
struct wlr_texture *gles_texture_from_buffer(struct wlr_renderer *wlr_renderer,
|
||||||
struct wlr_buffer *buffer) {
|
struct wlr_buffer *buffer) {
|
||||||
struct wlr_gles2_renderer *renderer = gles2_get_renderer(wlr_renderer);
|
struct wlr_gles_renderer *renderer = gles_get_renderer(wlr_renderer);
|
||||||
|
|
||||||
void *data;
|
void *data;
|
||||||
uint32_t format;
|
uint32_t format;
|
||||||
size_t stride;
|
size_t stride;
|
||||||
struct wlr_dmabuf_attributes dmabuf;
|
struct wlr_dmabuf_attributes dmabuf;
|
||||||
if (wlr_buffer_get_dmabuf(buffer, &dmabuf)) {
|
if (wlr_buffer_get_dmabuf(buffer, &dmabuf)) {
|
||||||
return gles2_texture_from_dmabuf(renderer, buffer, &dmabuf);
|
return gles_texture_from_dmabuf(renderer, buffer, &dmabuf);
|
||||||
} else if (wlr_buffer_begin_data_ptr_access(buffer,
|
} else if (wlr_buffer_begin_data_ptr_access(buffer,
|
||||||
WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride)) {
|
WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &format, &stride)) {
|
||||||
struct wlr_texture *tex = gles2_texture_from_pixels(wlr_renderer,
|
struct wlr_texture *tex = gles_texture_from_pixels(wlr_renderer,
|
||||||
format, stride, buffer->width, buffer->height, data);
|
format, stride, buffer->width, buffer->height, data);
|
||||||
wlr_buffer_end_data_ptr_access(buffer);
|
wlr_buffer_end_data_ptr_access(buffer);
|
||||||
return tex;
|
return tex;
|
||||||
|
|
@ -429,10 +438,10 @@ struct wlr_texture *gles2_texture_from_buffer(struct wlr_renderer *wlr_renderer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_gles2_texture_get_attribs(struct wlr_texture *wlr_texture,
|
void wlr_gles_texture_get_attribs(struct wlr_texture *wlr_texture,
|
||||||
struct wlr_gles2_texture_attribs *attribs) {
|
struct wlr_gles_texture_attribs *attribs) {
|
||||||
struct wlr_gles2_texture *texture = gles2_get_texture(wlr_texture);
|
struct wlr_gles_texture *texture = gles_get_texture(wlr_texture);
|
||||||
*attribs = (struct wlr_gles2_texture_attribs){
|
*attribs = (struct wlr_gles_texture_attribs){
|
||||||
.target = texture->target,
|
.target = texture->target,
|
||||||
.tex = texture->tex,
|
.tex = texture->tex,
|
||||||
.has_alpha = texture->has_alpha,
|
.has_alpha = texture->has_alpha,
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
glesv2 = dependency('glesv2', required: 'gles2' in renderers)
|
|
||||||
|
|
||||||
if not (glesv2.found() and internal_features['egl'])
|
|
||||||
subdir_done()
|
|
||||||
endif
|
|
||||||
|
|
||||||
glslang = find_program('glslang', 'glslangValidator', native: true, required: false, disabler: true)
|
|
||||||
|
|
||||||
features += { 'gles2-renderer': true }
|
|
||||||
wlr_deps += glesv2
|
|
||||||
|
|
||||||
wlr_files += files(
|
|
||||||
'pass.c',
|
|
||||||
'pixel_format.c',
|
|
||||||
'renderer.c',
|
|
||||||
'texture.c',
|
|
||||||
)
|
|
||||||
|
|
||||||
subdir('shaders')
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
renderers = get_option('renderers')
|
renderers = get_option('renderers')
|
||||||
if 'auto' in renderers and get_option('auto_features').enabled()
|
if 'auto' in renderers and get_option('auto_features').enabled()
|
||||||
renderers = ['gles2', 'vulkan']
|
renderers = ['gles2', 'gles3', 'vulkan']
|
||||||
elif 'auto' in renderers and get_option('auto_features').disabled()
|
elif 'auto' in renderers and get_option('auto_features').disabled()
|
||||||
renderers = []
|
renderers = []
|
||||||
endif
|
endif
|
||||||
|
|
@ -25,8 +25,8 @@ endif
|
||||||
|
|
||||||
internal_config.set10('HAVE_EVENTFD', cc.has_header('sys/eventfd.h'))
|
internal_config.set10('HAVE_EVENTFD', cc.has_header('sys/eventfd.h'))
|
||||||
|
|
||||||
if 'gles2' in renderers or 'auto' in renderers
|
if 'gles2' in renderers or 'gles3' in renderers or 'auto' in renderers
|
||||||
egl = dependency('egl', required: 'gles2' in renderers)
|
egl = dependency('egl', required: 'gles2' in renderers or 'gles3' in renderers)
|
||||||
if egl.found()
|
if egl.found()
|
||||||
eglext_version = cc.get_define(
|
eglext_version = cc.get_define(
|
||||||
'EGL_EGLEXT_VERSION',
|
'EGL_EGLEXT_VERSION',
|
||||||
|
|
@ -36,18 +36,18 @@ if 'gles2' in renderers or 'auto' in renderers
|
||||||
if eglext_version < 20210604
|
if eglext_version < 20210604
|
||||||
egl = dependency(
|
egl = dependency(
|
||||||
'',
|
'',
|
||||||
required: 'gles2' in renderers,
|
required: 'gles2' in renderers or 'gles3' in renderers,
|
||||||
not_found_message: 'EGL headers too old',
|
not_found_message: 'EGL headers too old',
|
||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
gbm = dependency('gbm', required: 'gles2' in renderers)
|
gbm = dependency('gbm', required: 'gles2' in renderers or 'gles3' in renderers)
|
||||||
if egl.found() and gbm.found()
|
if egl.found() and gbm.found()
|
||||||
wlr_deps += [egl, gbm]
|
wlr_deps += [egl, gbm]
|
||||||
wlr_files += files('egl.c')
|
wlr_files += files('egl.c')
|
||||||
internal_features += { 'egl': true }
|
internal_features += { 'egl': true }
|
||||||
endif
|
endif
|
||||||
subdir('gles2')
|
subdir('gles')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if 'vulkan' in renderers or 'auto' in renderers
|
if 'vulkan' in renderers or 'auto' in renderers
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@
|
||||||
|
|
||||||
#include <wlr/config.h>
|
#include <wlr/config.h>
|
||||||
|
|
||||||
#if WLR_HAS_GLES2_RENDERER
|
#if WLR_HAS_GLES2_RENDERER || WLR_HAS_GLES3_RENDERER
|
||||||
#include <wlr/render/egl.h>
|
#include <wlr/render/egl.h>
|
||||||
#include <wlr/render/gles2.h>
|
#include <wlr/render/gles.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WLR_HAS_VULKAN_RENDERER
|
#if WLR_HAS_VULKAN_RENDERER
|
||||||
|
|
@ -220,6 +220,7 @@ static struct wlr_renderer *renderer_autocreate(struct wlr_backend *backend, int
|
||||||
const char *renderer_options[] = {
|
const char *renderer_options[] = {
|
||||||
"auto",
|
"auto",
|
||||||
"gles2",
|
"gles2",
|
||||||
|
"gles3",
|
||||||
"vulkan",
|
"vulkan",
|
||||||
"pixman",
|
"pixman",
|
||||||
NULL
|
NULL
|
||||||
|
|
@ -236,9 +237,9 @@ static struct wlr_renderer *renderer_autocreate(struct wlr_backend *backend, int
|
||||||
log_creation_failure(is_auto, "Cannot create GLES2 renderer: no DRM FD available");
|
log_creation_failure(is_auto, "Cannot create GLES2 renderer: no DRM FD available");
|
||||||
} else {
|
} else {
|
||||||
#if WLR_HAS_GLES2_RENDERER
|
#if WLR_HAS_GLES2_RENDERER
|
||||||
renderer = wlr_gles2_renderer_create_with_drm_fd(drm_fd);
|
renderer = wlr_gles_renderer_create_with_drm_fd(drm_fd, GLES2);
|
||||||
#else
|
#else
|
||||||
wlr_log(WLR_ERROR, "Cannot create GLES renderer: disabled at compile-time");
|
wlr_log(WLR_ERROR, "Cannot create GLES2 renderer: disabled at compile-time");
|
||||||
#endif
|
#endif
|
||||||
if (renderer) {
|
if (renderer) {
|
||||||
goto out;
|
goto out;
|
||||||
|
|
@ -248,6 +249,23 @@ static struct wlr_renderer *renderer_autocreate(struct wlr_backend *backend, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((is_auto && WLR_HAS_GLES3_RENDERER) || strcmp(renderer_name, "gles3") == 0) {
|
||||||
|
if (!open_preferred_drm_fd(backend, &drm_fd, &own_drm_fd)) {
|
||||||
|
log_creation_failure(is_auto, "Cannot create GLES3 renderer: no DRM FD available");
|
||||||
|
} else {
|
||||||
|
#if WLR_HAS_GLES3_RENDERER
|
||||||
|
renderer = wlr_gles_renderer_create_with_drm_fd(drm_fd, GLES3);
|
||||||
|
#else
|
||||||
|
wlr_log(WLR_ERROR, "Cannot create GLES3 renderer: disabled at compile-time");
|
||||||
|
#endif
|
||||||
|
if (renderer) {
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
|
log_creation_failure(is_auto, "Failed to create a GLES3 renderer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((is_auto && WLR_HAS_VULKAN_RENDERER) || strcmp(renderer_name, "vulkan") == 0) {
|
if ((is_auto && WLR_HAS_VULKAN_RENDERER) || strcmp(renderer_name, "vulkan") == 0) {
|
||||||
if (!open_preferred_drm_fd(backend, &drm_fd, &own_drm_fd)) {
|
if (!open_preferred_drm_fd(backend, &drm_fd, &own_drm_fd)) {
|
||||||
log_creation_failure(is_auto, "Cannot create Vulkan renderer: no DRM FD available");
|
log_creation_failure(is_auto, "Cannot create Vulkan renderer: no DRM FD available");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue