@@ -684,6 +684,7 @@ weston_dmabuf_feedback_destroy(struct weston_dmabuf_feedback *dmabuf_feedback)
684
684
wl_resource_for_each_safe (res , res_tmp , & dmabuf_feedback -> resource_list ) {
685
685
wl_list_remove (wl_resource_get_link (res ));
686
686
wl_list_init (wl_resource_get_link (res ));
687
+ wl_resource_set_user_data (res , NULL );
687
688
}
688
689
689
690
free (dmabuf_feedback );
@@ -786,6 +787,7 @@ weston_dmabuf_feedback_send_all(struct weston_dmabuf_feedback *dmabuf_feedback,
786
787
{
787
788
struct wl_resource * res ;
788
789
790
+ assert (!wl_list_empty (& dmabuf_feedback -> resource_list ));
789
791
wl_resource_for_each (res , & dmabuf_feedback -> resource_list )
790
792
weston_dmabuf_feedback_send (dmabuf_feedback ,
791
793
format_table , res , false);
@@ -794,7 +796,16 @@ weston_dmabuf_feedback_send_all(struct weston_dmabuf_feedback *dmabuf_feedback,
794
796
static void
795
797
dmabuf_feedback_resource_destroy (struct wl_resource * resource )
796
798
{
799
+ struct weston_surface * surface =
800
+ wl_resource_get_user_data (resource );
801
+
797
802
wl_list_remove (wl_resource_get_link (resource ));
803
+
804
+ if (surface &&
805
+ wl_list_empty (& surface -> dmabuf_feedback -> resource_list )) {
806
+ weston_dmabuf_feedback_destroy (surface -> dmabuf_feedback );
807
+ surface -> dmabuf_feedback = NULL ;
808
+ }
798
809
}
799
810
800
811
static void
@@ -810,7 +821,8 @@ zwp_linux_dmabuf_feedback_implementation = {
810
821
811
822
static struct wl_resource *
812
823
dmabuf_feedback_resource_create (struct wl_resource * dmabuf_resource ,
813
- struct wl_client * client , uint32_t dmabuf_feedback_id )
824
+ struct wl_client * client , uint32_t dmabuf_feedback_id ,
825
+ struct weston_surface * surface )
814
826
{
815
827
struct wl_resource * dmabuf_feedback_res ;
816
828
uint32_t version ;
@@ -826,7 +838,7 @@ dmabuf_feedback_resource_create(struct wl_resource *dmabuf_resource,
826
838
wl_list_init (wl_resource_get_link (dmabuf_feedback_res ));
827
839
wl_resource_set_implementation (dmabuf_feedback_res ,
828
840
& zwp_linux_dmabuf_feedback_implementation ,
829
- NULL , dmabuf_feedback_resource_destroy );
841
+ surface , dmabuf_feedback_resource_destroy );
830
842
831
843
return dmabuf_feedback_res ;
832
844
}
@@ -842,7 +854,8 @@ linux_dmabuf_get_default_feedback(struct wl_client *client,
842
854
843
855
dmabuf_feedback_resource =
844
856
dmabuf_feedback_resource_create (dmabuf_resource ,
845
- client , dmabuf_feedback_id );
857
+ client , dmabuf_feedback_id ,
858
+ NULL );
846
859
if (!dmabuf_feedback_resource ) {
847
860
wl_resource_post_no_memory (dmabuf_resource );
848
861
return ;
@@ -853,22 +866,55 @@ linux_dmabuf_get_default_feedback(struct wl_client *client,
853
866
dmabuf_feedback_resource , true);
854
867
}
855
868
869
+ static int
870
+ create_surface_dmabuf_feedback (struct weston_compositor * ec ,
871
+ struct weston_surface * surface )
872
+ {
873
+ struct weston_dmabuf_feedback_tranche * tranche ;
874
+ dev_t main_device = ec -> default_dmabuf_feedback -> main_device ;
875
+ uint32_t flags = 0 ;
876
+
877
+ surface -> dmabuf_feedback = weston_dmabuf_feedback_create (main_device );
878
+ if (!surface -> dmabuf_feedback )
879
+ return -1 ;
880
+
881
+ tranche = weston_dmabuf_feedback_tranche_create (surface -> dmabuf_feedback ,
882
+ ec -> dmabuf_feedback_format_table ,
883
+ main_device , flags ,
884
+ RENDERER_PREF );
885
+ if (!tranche ) {
886
+ weston_dmabuf_feedback_destroy (surface -> dmabuf_feedback );
887
+ surface -> dmabuf_feedback = NULL ;
888
+ return -1 ;
889
+ }
890
+
891
+ return 0 ;
892
+ }
893
+
856
894
static void
857
895
linux_dmabuf_get_per_surface_feedback (struct wl_client * client ,
858
896
struct wl_resource * dmabuf_resource ,
859
897
uint32_t dmabuf_feedback_id ,
860
898
struct wl_resource * surface_resource )
861
899
{
900
+ struct weston_compositor * compositor =
901
+ wl_resource_get_user_data (dmabuf_resource );
862
902
struct weston_surface * surface =
863
903
wl_resource_get_user_data (surface_resource );
864
904
struct wl_resource * dmabuf_feedback_resource ;
905
+ int ret ;
865
906
866
907
dmabuf_feedback_resource =
867
908
dmabuf_feedback_resource_create (dmabuf_resource ,
868
- client , dmabuf_feedback_id );
869
- if (!dmabuf_feedback_resource ) {
870
- wl_resource_post_no_memory (dmabuf_resource );
871
- return ;
909
+ client , dmabuf_feedback_id ,
910
+ surface );
911
+ if (!dmabuf_feedback_resource )
912
+ goto err ;
913
+
914
+ if (!surface -> dmabuf_feedback ) {
915
+ ret = create_surface_dmabuf_feedback (compositor , surface );
916
+ if (ret < 0 )
917
+ goto err_feedback ;
872
918
}
873
919
874
920
/* Surface dma-buf feedback is dynamic and may need to be resent to
@@ -879,6 +925,13 @@ linux_dmabuf_get_per_surface_feedback(struct wl_client *client,
879
925
weston_dmabuf_feedback_send (surface -> dmabuf_feedback ,
880
926
surface -> compositor -> dmabuf_feedback_format_table ,
881
927
dmabuf_feedback_resource , true);
928
+ return ;
929
+
930
+ err_feedback :
931
+ wl_resource_set_user_data (dmabuf_feedback_resource , NULL );
932
+ wl_resource_destroy (dmabuf_feedback_resource );
933
+ err :
934
+ wl_resource_post_no_memory (dmabuf_resource );
882
935
}
883
936
884
937
/** Get the linux_dmabuf_buffer from a wl_buffer resource
0 commit comments