@ -114,16 +114,6 @@ struct egl_image {
int refcount ;
int refcount ;
} ;
} ;
struct dmabuf_image {
struct linux_dmabuf_buffer * dmabuf ;
int num_images ;
struct egl_image * images [ 3 ] ;
struct wl_list link ;
enum gl_shader_texture_variant shader_variant ;
} ;
struct dmabuf_format {
struct dmabuf_format {
uint32_t format ;
uint32_t format ;
struct wl_list link ;
struct wl_list link ;
@ -403,32 +393,6 @@ egl_image_unref(struct egl_image *image)
return 0 ;
return 0 ;
}
}
static struct dmabuf_image *
dmabuf_image_create ( void )
{
struct dmabuf_image * img ;
img = zalloc ( sizeof * img ) ;
wl_list_init ( & img - > link ) ;
return img ;
}
static void
dmabuf_image_destroy ( struct dmabuf_image * image )
{
int i ;
for ( i = 0 ; i < image - > num_images ; + + i )
egl_image_unref ( image - > images [ i ] ) ;
if ( image - > dmabuf )
linux_dmabuf_buffer_set_user_data ( image - > dmabuf , NULL , NULL ) ;
wl_list_remove ( & image - > link ) ;
free ( image ) ;
}
# define max(a, b) (((a) > (b)) ? (a) : (b))
# define max(a, b) (((a) > (b)) ? (a) : (b))
# define min(a, b) (((a) > (b)) ? (b) : (a))
# define min(a, b) (((a) > (b)) ? (b) : (a))
@ -2347,9 +2311,11 @@ gl_renderer_attach_egl(struct weston_surface *es, struct weston_buffer *buffer)
static void
static void
gl_renderer_destroy_dmabuf ( struct linux_dmabuf_buffer * dmabuf )
gl_renderer_destroy_dmabuf ( struct linux_dmabuf_buffer * dmabuf )
{
{
struct dmabuf_image * image = linux_dmabuf_buffer_get_user_data ( dmabuf ) ;
struct gl_buffer_state * gb =
linux_dmabuf_buffer_get_user_data ( dmabuf ) ;
dmabuf_image_destroy ( image ) ;
linux_dmabuf_buffer_set_user_data ( dmabuf , NULL , NULL ) ;
destroy_buffer_state ( gb ) ;
}
}
static struct egl_image *
static struct egl_image *
@ -2573,14 +2539,13 @@ import_dmabuf_single_plane(struct gl_renderer *gr,
}
}
static bool
static bool
import_yuv_dmabuf ( struct gl_renderer * gr ,
import_yuv_dmabuf ( struct gl_renderer * gr , struct gl_buffer_state * gb ,
struct dmabuf_image * image )
struct dmabuf_attributes * attributes )
{
{
unsigned i ;
unsigned i ;
int j ;
int j ;
int ret ;
int ret ;
struct yuv_format_descriptor * format = NULL ;
struct yuv_format_descriptor * format = NULL ;
struct dmabuf_attributes * attributes = & image - > dmabuf - > attributes ;
char fmt [ 4 ] ;
char fmt [ 4 ] ;
for ( i = 0 ; i < ARRAY_LENGTH ( yuv_formats ) ; + + i ) {
for ( i = 0 ; i < ARRAY_LENGTH ( yuv_formats ) ; + + i ) {
@ -2607,31 +2572,32 @@ import_yuv_dmabuf(struct gl_renderer *gr,
}
}
for ( j = 0 ; j < format - > output_planes ; + + j ) {
for ( j = 0 ; j < format - > output_planes ; + + j ) {
image - > images [ j ] = import_dmabuf_single_plane ( gr , attributes ,
gb - > images [ j ] = import_dmabuf_single_plane ( gr , attributes ,
& format - > plane [ j ] ) ;
& format - > plane [ j ] ) ;
if ( ! image - > images [ j ] ) {
if ( ! gb - > images [ j ] ) {
while ( j ) {
while ( - - j > = 0 ) {
ret = egl_image_unref ( image - > images [ - - j ] ) ;
ret = egl_image_unref ( gb - > images [ j ] ) ;
assert ( ret = = 0 ) ;
assert ( ret = = 0 ) ;
gb - > images [ j ] = NULL ;
}
}
return false ;
return false ;
}
}
}
}
image - > num_images = format - > output_planes ;
gb - > num_images = format - > output_planes ;
switch ( format - > texture_type ) {
switch ( format - > texture_type ) {
case TEXTURE_Y_XUXV_WL :
case TEXTURE_Y_XUXV_WL :
image - > shader_variant = SHADER_VARIANT_Y_XUXV ;
gb - > shader_variant = SHADER_VARIANT_Y_XUXV ;
break ;
break ;
case TEXTURE_Y_UV_WL :
case TEXTURE_Y_UV_WL :
image - > shader_variant = SHADER_VARIANT_Y_UV ;
gb - > shader_variant = SHADER_VARIANT_Y_UV ;
break ;
break ;
case TEXTURE_Y_U_V_WL :
case TEXTURE_Y_U_V_WL :
image - > shader_variant = SHADER_VARIANT_Y_U_V ;
gb - > shader_variant = SHADER_VARIANT_Y_U_V ;
break ;
break ;
case TEXTURE_XYUV_WL :
case TEXTURE_XYUV_WL :
image - > shader_variant = SHADER_VARIANT_XYUV ;
gb - > shader_variant = SHADER_VARIANT_XYUV ;
break ;
break ;
default :
default :
assert ( false ) ;
assert ( false ) ;
@ -2725,41 +2691,46 @@ choose_texture_target(struct gl_renderer *gr,
}
}
}
}
static struct dmabuf_imag e *
static struct gl_buffer_stat e *
import_dmabuf ( struct gl_renderer * gr ,
import_dmabuf ( struct gl_renderer * gr ,
struct linux_dmabuf_buffer * dmabuf )
struct linux_dmabuf_buffer * dmabuf )
{
{
struct egl_image * egl_image ;
struct egl_image * egl_image ;
struct dmabuf_image * image ;
struct gl_buffer_state * gb = zalloc ( sizeof ( * gb ) ) ;
GLenum target ;
if ( ! pixel_format_get_info ( dmabuf - > attributes . format ) )
if ( ! pixel_format_get_info ( dmabuf - > attributes . format ) )
return NULL ;
return NULL ;
image = dmabuf_image_create ( ) ;
gb = zalloc ( sizeof ( * gb ) ) ;
image - > dmabuf = dmabuf ;
if ( ! gb )
return NULL ;
wl_list_init ( & gb - > destroy_listener . link ) ;
egl_image = import_simple_dmabuf ( gr , & dmabuf - > attributes ) ;
egl_image = import_simple_dmabuf ( gr , & dmabuf - > attributes ) ;
if ( egl_image ) {
if ( egl_image ) {
image - > num_images = 1 ;
GLenum target = choose_texture_target ( gr , & dmabuf - > attributes ) ;
image - > images [ 0 ] = egl_image ;
target = choose_texture_target ( gr , & dmabuf - > attributes ) ;
gb - > num_images = 1 ;
gb - > images [ 0 ] = egl_image ;
switch ( target ) {
switch ( target ) {
case GL_TEXTURE_2D :
case GL_TEXTURE_2D :
image - > shader_variant = SHADER_VARIANT_RGBA ;
gb - > shader_variant = SHADER_VARIANT_RGBA ;
break ;
break ;
default :
default :
image - > shader_variant = SHADER_VARIANT_EXTERNAL ;
gb - > shader_variant = SHADER_VARIANT_EXTERNAL ;
}
} else {
if ( ! import_yuv_dmabuf ( gr , image ) ) {
dmabuf_image_destroy ( image ) ;
return NULL ;
}
}
return gb ;
}
}
return image ;
if ( ! import_yuv_dmabuf ( gr , gb , & dmabuf - > attributes ) ) {
destroy_buffer_state ( gb ) ;
return NULL ;
}
return gb ;
}
}
static void
static void
@ -2868,7 +2839,7 @@ gl_renderer_import_dmabuf(struct weston_compositor *ec,
struct linux_dmabuf_buffer * dmabuf )
struct linux_dmabuf_buffer * dmabuf )
{
{
struct gl_renderer * gr = get_renderer ( ec ) ;
struct gl_renderer * gr = get_renderer ( ec ) ;
struct dmabuf_image * image ;
struct gl_buffer_state * gb ;
int i ;
int i ;
assert ( gr - > has_dmabuf_import ) ;
assert ( gr - > has_dmabuf_import ) ;
@ -2889,12 +2860,11 @@ gl_renderer_import_dmabuf(struct weston_compositor *ec,
if ( dmabuf - > attributes . flags & ~ ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT )
if ( dmabuf - > attributes . flags & ~ ZWP_LINUX_BUFFER_PARAMS_V1_FLAGS_Y_INVERT )
return false ;
return false ;
image = import_dmabuf ( gr , dmabuf ) ;
gb = import_dmabuf ( gr , dmabuf ) ;
if ( ! image )
if ( ! gb )
return false ;
return false ;
wl_list_insert ( & gr - > dmabuf_images , & image - > link ) ;
linux_dmabuf_buffer_set_user_data ( dmabuf , gb ,
linux_dmabuf_buffer_set_user_data ( dmabuf , image ,
gl_renderer_destroy_dmabuf ) ;
gl_renderer_destroy_dmabuf ) ;
return true ;
return true ;
@ -2906,38 +2876,52 @@ gl_renderer_attach_dmabuf(struct weston_surface *surface,
{
{
struct gl_renderer * gr = get_renderer ( surface - > compositor ) ;
struct gl_renderer * gr = get_renderer ( surface - > compositor ) ;
struct gl_surface_state * gs = get_surface_state ( surface ) ;
struct gl_surface_state * gs = get_surface_state ( surface ) ;
struct gl_buffer_state * gb = & gs - > buffer ;
struct gl_buffer_state * gb ;
struct linux_dmabuf_buffer * dmabuf = buffer - > dmabuf ;
struct linux_dmabuf_buffer * dmabuf = buffer - > dmabuf ;
struct dmabuf_image * image ;
GLenum target ;
GLenum target ;
int i ;
int i ;
for ( i = 0 ; i < gb - > num_images ; i + + )
for ( i = 0 ; i < gs - > buffer . num_images ; i + + )
egl_image_unref ( gb - > images [ i ] ) ;
egl_image_unref ( gs - > buffer . images [ i ] ) ;
gb - > num_images = 0 ;
gs - > buffer . num_images = 0 ;
if ( buffer - > direct_display )
if ( buffer - > direct_display )
return true ;
return true ;
image = linux_dmabuf_buffer_get_user_data ( dmabuf ) ;
/* Thanks to linux-dmabuf being totally independent of libweston,
* the first time a dmabuf is attached , the gl_buffer_state will
/* The dmabuf_image should have been created during the import */
* only be set as userdata on the dmabuf , not on the weston_buffer .
assert ( image ! = NULL ) ;
* When this happens , steal it away into the weston_buffer . */
if ( ! buffer - > renderer_private ) {
gb = linux_dmabuf_buffer_get_user_data ( dmabuf ) ;
assert ( gb ) ;
linux_dmabuf_buffer_set_user_data ( dmabuf , NULL , NULL ) ;
buffer - > renderer_private = gb ;
gb - > destroy_listener . notify = handle_buffer_destroy ;
wl_signal_add ( & buffer - > destroy_signal , & gb - > destroy_listener ) ;
}
gb - > num_images = image - > num_images ;
assert ( buffer - > renderer_private ) ;
assert ( linux_dmabuf_buffer_get_user_data ( dmabuf ) = = NULL ) ;
gb = buffer - > renderer_private ;
/* The gl_buffer_state stored in the weston_buffer holds a reference
* on the EGLImages ; we take another ref when we copy into the
* gl_surface_state so we don ' t lose track of anything . This is
* temporary and will be removed when gl_surface_state starts
* referencing rather than inlining the gl_buffer_state . */
memcpy ( & gs - > buffer , gb , sizeof ( * gb ) ) ;
for ( i = 0 ; i < gb - > num_images ; + + i )
for ( i = 0 ; i < gb - > num_images ; + + i )
gb - > images [ i ] = egl_image_ref ( image - > images [ i ] ) ;
gs - > buffer . images [ i ] = egl_image_ref ( gs - > buffer . images [ i ] ) ;
target = gl_shader_texture_variant_get_target ( image - > shader_variant ) ;
target = gl_shader_texture_variant_get_target ( gs - > buffer . shader_variant ) ;
ensure_textures ( gs , target , gb - > num_images ) ;
ensure_textures ( gs , target , gb - > num_images ) ;
for ( i = 0 ; i < gb - > num_images ; + + i ) {
for ( i = 0 ; i < gs - > buffer . num_images ; + + i ) {
glActiveTexture ( GL_TEXTURE0 + i ) ;
glActiveTexture ( GL_TEXTURE0 + i ) ;
glBindTexture ( target , gs - > textures [ i ] ) ;
glBindTexture ( target , gs - > textures [ i ] ) ;
gr - > image_target_texture_2d ( target , gb - > images [ i ] - > image ) ;
gr - > image_target_texture_2d ( target , gs - > buffer . images [ i ] - > image ) ;
}
}
gb - > shader_variant = image - > shader_variant ;
return true ;
return true ;
}
}
@ -3610,7 +3594,6 @@ static void
gl_renderer_destroy ( struct weston_compositor * ec )
gl_renderer_destroy ( struct weston_compositor * ec )
{
{
struct gl_renderer * gr = get_renderer ( ec ) ;
struct gl_renderer * gr = get_renderer ( ec ) ;
struct dmabuf_image * image , * next ;
struct dmabuf_format * format , * next_format ;
struct dmabuf_format * format , * next_format ;
wl_signal_emit ( & gr - > destroy_signal , gr ) ;
wl_signal_emit ( & gr - > destroy_signal , gr ) ;
@ -3627,9 +3610,6 @@ gl_renderer_destroy(struct weston_compositor *ec)
EGL_NO_SURFACE , EGL_NO_SURFACE ,
EGL_NO_SURFACE , EGL_NO_SURFACE ,
EGL_NO_CONTEXT ) ;
EGL_NO_CONTEXT ) ;
wl_list_for_each_safe ( image , next , & gr - > dmabuf_images , link )
dmabuf_image_destroy ( image ) ;
wl_list_for_each_safe ( format , next_format , & gr - > dmabuf_formats , link )
wl_list_for_each_safe ( format , next_format , & gr - > dmabuf_formats , link )
dmabuf_format_destroy ( format ) ;
dmabuf_format_destroy ( format ) ;
@ -3783,7 +3763,6 @@ gl_renderer_display_create(struct weston_compositor *ec,
if ( gr - > has_native_fence_sync & & gr - > has_wait_sync )
if ( gr - > has_native_fence_sync & & gr - > has_wait_sync )
ec - > capabilities | = WESTON_CAP_EXPLICIT_SYNC ;
ec - > capabilities | = WESTON_CAP_EXPLICIT_SYNC ;
wl_list_init ( & gr - > dmabuf_images ) ;
if ( gr - > has_dmabuf_import ) {
if ( gr - > has_dmabuf_import ) {
gr - > base . import_dmabuf = gl_renderer_import_dmabuf ;
gr - > base . import_dmabuf = gl_renderer_import_dmabuf ;
gr - > base . get_supported_formats = gl_renderer_get_supported_formats ;
gr - > base . get_supported_formats = gl_renderer_get_supported_formats ;