1 /*
2  * Copyright (C) 2018 Red Hat
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19 
20 #ifndef META_KMS_UPDATE_H
21 #define META_KMS_UPDATE_H
22 
23 #include <glib-object.h>
24 #include <glib.h>
25 #include <stdint.h>
26 #include <xf86drmMode.h>
27 
28 #include "backends/meta-monitor-transform.h"
29 #include "backends/native/meta-drm-buffer.h"
30 #include "backends/native/meta-kms-types.h"
31 #include "meta/boxes.h"
32 
33 typedef enum _MetaKmsFeedbackResult
34 {
35   META_KMS_FEEDBACK_PASSED,
36   META_KMS_FEEDBACK_FAILED,
37 } MetaKmsFeedbackResult;
38 
39 typedef enum _MetaKmsAssignPlaneFlag
40 {
41   META_KMS_ASSIGN_PLANE_FLAG_NONE = 0,
42   META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED = 1 << 0,
43   META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1,
44 } MetaKmsAssignPlaneFlag;
45 
46 enum _MetaKmsPageFlipListenerFlag
47 {
48   META_KMS_PAGE_FLIP_LISTENER_FLAG_NONE = 0,
49   META_KMS_PAGE_FLIP_LISTENER_FLAG_DROP_ON_ERROR = 1 << 0,
50 };
51 
52 struct _MetaKmsPageFlipListenerVtable
53 {
54   void (* flipped) (MetaKmsCrtc  *crtc,
55                     unsigned int  sequence,
56                     unsigned int  tv_sec,
57                     unsigned int  tv_usec,
58                     gpointer      user_data);
59 
60   void (* ready) (MetaKmsCrtc *crtc,
61                   gpointer     user_data);
62 
63   void (* mode_set_fallback) (MetaKmsCrtc *crtc,
64                               gpointer     user_data);
65 
66   void (* discarded) (MetaKmsCrtc  *crtc,
67                       gpointer      user_data,
68                       const GError *error);
69 };
70 
71 typedef int (* MetaKmsCustomPageFlipFunc) (gpointer custom_page_flip_data,
72                                            gpointer user_data);
73 
74 typedef struct _MetaKmsPlaneFeedback
75 {
76   MetaKmsPlane *plane;
77   MetaKmsCrtc *crtc;
78   GError *error;
79 } MetaKmsPlaneFeedback;
80 
81 typedef void (* MetaKmsResultListenerFunc) (const MetaKmsFeedback *feedback,
82                                             gpointer               user_data);
83 
84 void meta_kms_feedback_free (MetaKmsFeedback *feedback);
85 
86 MetaKmsFeedbackResult meta_kms_feedback_get_result (const MetaKmsFeedback *feedback);
87 
88 GList * meta_kms_feedback_get_failed_planes (const MetaKmsFeedback *feedback);
89 
90 const GError * meta_kms_feedback_get_error (const MetaKmsFeedback *feedback);
91 
92 MetaKmsUpdate * meta_kms_update_new (MetaKmsDevice *device);
93 
94 void meta_kms_update_free (MetaKmsUpdate *update);
95 
96 void meta_kms_update_set_underscanning (MetaKmsUpdate    *update,
97                                         MetaKmsConnector *connector,
98                                         uint64_t          hborder,
99                                         uint64_t          vborder);
100 
101 void meta_kms_update_unset_underscanning (MetaKmsUpdate    *update,
102                                           MetaKmsConnector *connector);
103 
104 void meta_kms_update_set_power_save (MetaKmsUpdate *update);
105 
106 void meta_kms_update_mode_set (MetaKmsUpdate *update,
107                                MetaKmsCrtc   *crtc,
108                                GList         *connectors,
109                                MetaKmsMode   *mode);
110 
111 void meta_kms_update_set_crtc_gamma (MetaKmsUpdate  *update,
112                                      MetaKmsCrtc    *crtc,
113                                      int             size,
114                                      const uint16_t *red,
115                                      const uint16_t *green,
116                                      const uint16_t *blue);
117 
118 void meta_kms_plane_assignment_set_fb_damage (MetaKmsPlaneAssignment *plane_assignment,
119                                               const int              *rectangles,
120                                               int                     n_rectangles);
121 
122 MetaKmsPlaneAssignment * meta_kms_update_assign_plane (MetaKmsUpdate          *update,
123                                                        MetaKmsCrtc            *crtc,
124                                                        MetaKmsPlane           *plane,
125                                                        MetaDrmBuffer          *buffer,
126                                                        MetaFixed16Rectangle    src_rect,
127                                                        MetaRectangle           dst_rect,
128                                                        MetaKmsAssignPlaneFlag  flags);
129 
130 MetaKmsPlaneAssignment * meta_kms_update_unassign_plane (MetaKmsUpdate *update,
131                                                          MetaKmsCrtc   *crtc,
132                                                          MetaKmsPlane  *plane);
133 
134 void meta_kms_update_add_page_flip_listener (MetaKmsUpdate                       *update,
135                                              MetaKmsCrtc                         *crtc,
136                                              const MetaKmsPageFlipListenerVtable *vtable,
137                                              MetaKmsPageFlipListenerFlag          flags,
138                                              gpointer                             user_data,
139                                              GDestroyNotify                       destroy_notify);
140 
141 void meta_kms_update_set_custom_page_flip (MetaKmsUpdate             *update,
142                                            MetaKmsCustomPageFlipFunc  func,
143                                            gpointer                   user_data);
144 
145 void meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assignment,
146                                                    int                     x,
147                                                    int                     y);
148 
149 void meta_kms_update_add_result_listener (MetaKmsUpdate             *update,
150                                           MetaKmsResultListenerFunc  func,
151                                           gpointer                   user_data);
152 
153 static inline MetaFixed16
meta_fixed_16_from_int(int16_t d)154 meta_fixed_16_from_int (int16_t d)
155 {
156   return d * 65536;
157 }
158 
159 static inline int16_t
meta_fixed_16_to_int(MetaFixed16 fixed)160 meta_fixed_16_to_int (MetaFixed16 fixed)
161 {
162   return fixed / 65536;
163 }
164 
165 static inline double
meta_fixed_16_to_double(MetaFixed16 fixed)166 meta_fixed_16_to_double (MetaFixed16 fixed)
167 {
168   return fixed / 65536.0;
169 }
170 
171 static inline MetaRectangle
meta_fixed_16_rectangle_to_rectangle(MetaFixed16Rectangle fixed_rect)172 meta_fixed_16_rectangle_to_rectangle (MetaFixed16Rectangle fixed_rect)
173 {
174   return (MetaRectangle) {
175     .x = meta_fixed_16_to_int (fixed_rect.x),
176     .y = meta_fixed_16_to_int (fixed_rect.y),
177     .width = meta_fixed_16_to_int (fixed_rect.width),
178     .height = meta_fixed_16_to_int (fixed_rect.height),
179   };
180 }
181 
182 G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsFeedback, meta_kms_feedback_free)
183 G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsUpdate, meta_kms_update_free)
184 
185 #endif /* META_KMS_UPDATE_H */
186