@ -207,13 +207,17 @@ static void gles2_render_ellipse_with_matrix(struct wlr_renderer *wlr_renderer,
static const enum wl_shm_format * gles2_renderer_formats (
static const enum wl_shm_format * gles2_renderer_formats (
struct wlr_renderer * wlr_renderer , size_t * len ) {
struct wlr_renderer * wlr_renderer , size_t * len ) {
return get_gles2_formats ( len ) ;
return get_gles2_wl_formats ( len ) ;
}
static bool gles2_format_supported ( struct wlr_renderer * wlr_renderer ,
enum wl_shm_format wl_fmt ) {
return get_gles2_format_from_wl ( wl_fmt ) ! = NULL ;
}
}
static bool gles2_resource_is_wl_drm_buffer ( struct wlr_renderer * wlr_renderer ,
static bool gles2_resource_is_wl_drm_buffer ( struct wlr_renderer * wlr_renderer ,
struct wl_resource * resource ) {
struct wl_resource * resource ) {
struct wlr_gles2_renderer * renderer =
struct wlr_gles2_renderer * renderer = gles2_get_renderer ( wlr_renderer ) ;
gles2_get_renderer ( wlr_renderer ) ;
if ( ! eglQueryWaylandBufferWL ) {
if ( ! eglQueryWaylandBufferWL ) {
return false ;
return false ;
@ -249,6 +253,33 @@ static int gles2_get_dmabuf_modifiers(struct wlr_renderer *wlr_renderer,
return wlr_egl_get_dmabuf_modifiers ( renderer - > egl , format , modifiers ) ;
return wlr_egl_get_dmabuf_modifiers ( renderer - > egl , format , modifiers ) ;
}
}
static enum wl_shm_format gles2_preferred_read_format (
struct wlr_renderer * wlr_renderer ) {
struct wlr_gles2_renderer * renderer =
gles2_get_renderer_in_context ( wlr_renderer ) ;
GLint gl_format = - 1 , gl_type = - 1 ;
PUSH_GLES2_DEBUG ;
glGetIntegerv ( GL_IMPLEMENTATION_COLOR_READ_FORMAT , & gl_format ) ;
glGetIntegerv ( GL_IMPLEMENTATION_COLOR_READ_TYPE , & gl_type ) ;
POP_GLES2_DEBUG ;
EGLint alpha_size = - 1 ;
eglGetConfigAttrib ( renderer - > egl - > display , renderer - > egl - > config ,
EGL_ALPHA_SIZE , & alpha_size ) ;
const struct wlr_gles2_pixel_format * fmt =
get_gles2_format_from_gl ( gl_format , gl_type , alpha_size > 0 ) ;
if ( fmt ! = NULL ) {
return fmt - > wl_format ;
}
if ( renderer - > exts . read_format_bgra_ext ) {
return WL_SHM_FORMAT_XRGB8888 ;
}
return WL_SHM_FORMAT_XBGR8888 ;
}
static bool gles2_read_pixels ( struct wlr_renderer * wlr_renderer ,
static bool gles2_read_pixels ( struct wlr_renderer * wlr_renderer ,
enum wl_shm_format wl_fmt , uint32_t * flags , uint32_t stride ,
enum wl_shm_format wl_fmt , uint32_t * flags , uint32_t stride ,
uint32_t width , uint32_t height , uint32_t src_x , uint32_t src_y ,
uint32_t width , uint32_t height , uint32_t src_x , uint32_t src_y ,
@ -262,6 +293,12 @@ static bool gles2_read_pixels(struct wlr_renderer *wlr_renderer,
return false ;
return false ;
}
}
if ( fmt - > gl_format = = GL_BGRA_EXT & & ! renderer - > exts . read_format_bgra_ext ) {
wlr_log ( WLR_ERROR ,
" Cannot read pixels: missing GL_EXT_read_format_bgra extension " ) ;
return false ;
}
PUSH_GLES2_DEBUG ;
PUSH_GLES2_DEBUG ;
// Make sure any pending drawing is finished before we try to read it
// Make sure any pending drawing is finished before we try to read it
@ -294,11 +331,6 @@ static bool gles2_read_pixels(struct wlr_renderer *wlr_renderer,
return glGetError ( ) = = GL_NO_ERROR ;
return glGetError ( ) = = GL_NO_ERROR ;
}
}
static bool gles2_format_supported ( struct wlr_renderer * wlr_renderer ,
enum wl_shm_format wl_fmt ) {
return get_gles2_format_from_wl ( wl_fmt ) ! = NULL ;
}
static struct wlr_texture * gles2_texture_from_pixels (
static struct wlr_texture * gles2_texture_from_pixels (
struct wlr_renderer * wlr_renderer , enum wl_shm_format wl_fmt ,
struct wlr_renderer * wlr_renderer , enum wl_shm_format wl_fmt ,
uint32_t stride , uint32_t width , uint32_t height , const void * data ) {
uint32_t stride , uint32_t width , uint32_t height , const void * data ) {
@ -342,7 +374,7 @@ static void gles2_destroy(struct wlr_renderer *wlr_renderer) {
glDeleteProgram ( renderer - > shaders . tex_ext . program ) ;
glDeleteProgram ( renderer - > shaders . tex_ext . program ) ;
POP_GLES2_DEBUG ;
POP_GLES2_DEBUG ;
if ( glDebugMessageCallbackKHR ) {
if ( renderer- > exts . debug_khr ) {
glDisable ( GL_DEBUG_OUTPUT_KHR ) ;
glDisable ( GL_DEBUG_OUTPUT_KHR ) ;
glDebugMessageCallbackKHR ( NULL , NULL ) ;
glDebugMessageCallbackKHR ( NULL , NULL ) ;
}
}
@ -360,12 +392,13 @@ static const struct wlr_renderer_impl renderer_impl = {
. render_quad_with_matrix = gles2_render_quad_with_matrix ,
. render_quad_with_matrix = gles2_render_quad_with_matrix ,
. render_ellipse_with_matrix = gles2_render_ellipse_with_matrix ,
. render_ellipse_with_matrix = gles2_render_ellipse_with_matrix ,
. formats = gles2_renderer_formats ,
. formats = gles2_renderer_formats ,
. format_supported = gles2_format_supported ,
. resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer ,
. resource_is_wl_drm_buffer = gles2_resource_is_wl_drm_buffer ,
. wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size ,
. wl_drm_buffer_get_size = gles2_wl_drm_buffer_get_size ,
. get_dmabuf_formats = gles2_get_dmabuf_formats ,
. get_dmabuf_formats = gles2_get_dmabuf_formats ,
. get_dmabuf_modifiers = gles2_get_dmabuf_modifiers ,
. get_dmabuf_modifiers = gles2_get_dmabuf_modifiers ,
. preferred_read_format = gles2_preferred_read_format ,
. read_pixels = gles2_read_pixels ,
. read_pixels = gles2_read_pixels ,
. format_supported = gles2_format_supported ,
. texture_from_pixels = gles2_texture_from_pixels ,
. texture_from_pixels = gles2_texture_from_pixels ,
. texture_from_wl_drm = gles2_texture_from_wl_drm ,
. texture_from_wl_drm = gles2_texture_from_wl_drm ,
. texture_from_dmabuf = gles2_texture_from_dmabuf ,
. texture_from_dmabuf = gles2_texture_from_dmabuf ,
@ -466,6 +499,24 @@ error:
return 0 ;
return 0 ;
}
}
static bool check_gl_ext ( const char * exts , const char * ext ) {
size_t extlen = strlen ( ext ) ;
const char * end = exts + strlen ( exts ) ;
while ( exts < end ) {
if ( exts [ 0 ] = = ' ' ) {
exts + + ;
continue ;
}
size_t n = strcspn ( exts , " " ) ;
if ( n = = extlen & & strncmp ( ext , exts , n ) = = 0 ) {
return true ;
}
exts + = n ;
}
return false ;
}
extern const GLchar quad_vertex_src [ ] ;
extern const GLchar quad_vertex_src [ ] ;
extern const GLchar quad_fragment_src [ ] ;
extern const GLchar quad_fragment_src [ ] ;
extern const GLchar ellipse_fragment_src [ ] ;
extern const GLchar ellipse_fragment_src [ ] ;
@ -487,14 +538,29 @@ struct wlr_renderer *wlr_gles2_renderer_create(struct wlr_egl *egl) {
wlr_renderer_init ( & renderer - > wlr_renderer , & renderer_impl ) ;
wlr_renderer_init ( & renderer - > wlr_renderer , & renderer_impl ) ;
renderer - > egl = egl ;
renderer - > egl = egl ;
wlr_egl_make_current ( renderer - > egl , EGL_NO_SURFACE , NULL ) ;
if ( ! wlr_egl_make_current ( renderer - > egl , EGL_NO_SURFACE , NULL ) ) {
free ( renderer ) ;
return NULL ;
}
renderer - > exts_str = ( const char * ) glGetString ( GL_EXTENSIONS ) ;
renderer - > exts_str = ( const char * ) glGetString ( GL_EXTENSIONS ) ;
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 , " Supported GLES2 extensions: %s " , renderer - > exts_str ) ;
wlr_log ( WLR_INFO , " Supported GLES2 extensions: %s " , renderer - > exts_str ) ;
if ( glDebugMessageCallbackKHR & & glDebugMessageControlKHR ) {
if ( ! check_gl_ext ( renderer - > exts_str , " GL_EXT_texture_format_BGRA8888 " ) ) {
wlr_log ( WLR_ERROR , " BGRA8888 format not supported by GLES2 " ) ;
free ( renderer ) ;
return NULL ;
}
renderer - > exts . read_format_bgra_ext =
check_gl_ext ( renderer - > exts_str , " GL_EXT_read_format_bgra " ) ;
renderer - > exts . debug_khr =
check_gl_ext ( renderer - > exts_str , " GL_KHR_debug " ) & &
glDebugMessageCallbackKHR & & glDebugMessageControlKHR ;
if ( renderer - > exts . debug_khr ) {
glEnable ( GL_DEBUG_OUTPUT_KHR ) ;
glEnable ( GL_DEBUG_OUTPUT_KHR ) ;
glEnable ( GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR ) ;
glEnable ( GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR ) ;
glDebugMessageCallbackKHR ( gles2_log , NULL ) ;
glDebugMessageCallbackKHR ( gles2_log , NULL ) ;
@ -570,7 +636,7 @@ error:
POP_GLES2_DEBUG ;
POP_GLES2_DEBUG ;
if ( glDebugMessageCallbackKHR ) {
if ( renderer- > exts . debug_khr ) {
glDisable ( GL_DEBUG_OUTPUT_KHR ) ;
glDisable ( GL_DEBUG_OUTPUT_KHR ) ;
glDebugMessageCallbackKHR ( NULL , NULL ) ;
glDebugMessageCallbackKHR ( NULL , NULL ) ;
}
}