1 #ifndef VIEW_TRANSFORM_HPP
2 #define VIEW_TRANSFORM_HPP
3 
4 #include <wayfire/view.hpp>
5 #include <wayfire/opengl.hpp>
6 
7 namespace wf
8 {
9 enum transformer_z_order_t
10 {
11     /* Simple 2D transforms */
12     TRANSFORMER_2D        = 1,
13     /* 3D transforms */
14     TRANSFORMER_3D        = 2,
15     /* Highlevels transforms and above do special effects, for ex. wobbly or fire */
16     TRANSFORMER_HIGHLEVEL = 500,
17     /* Do not use Z oder blur or more,
18      * except if you are willing to break it */
19     TRANSFORMER_BLUR      = 999,
20 };
21 
22 class view_transformer_t
23 {
24   public:
25     /**
26      * Get the Z ordering of the transformer, e.g the order in which it should
27      * be applied relative to the other transformers on the same view.
28      * Higher numbers indicate that the transform should be applied later.
29      *
30      * @return The Z order of the transformer.
31      */
32     virtual uint32_t get_z_order() = 0;
33 
34     /**
35      * Transform the opaque region of the view.
36      *
37      * It must be guaranteed that the pixels part of the returned region are
38      * opaque. The default implementation simply returns an empty region.
39      *
40      * @param box The bounding box of the view up to this transformer.
41      * @param region The opaque region to transform.
42      *
43      * @return The transformed opaque region.
44      */
45     virtual wf::region_t transform_opaque_region(
46         wf::geometry_t box, wf::region_t region);
47 
48     /**
49      * Transform a single point.
50      *
51      * @param view The bounding box of the view, in output-local
52      *   coordinates.
53      * @param point The point to transform, in output-local coordinates.
54      *
55      * @return The point after transforming it, in output-local coordinates.
56      */
57     virtual wf::pointf_t transform_point(
58         wf::geometry_t view, wf::pointf_t point) = 0;
59 
60     /**
61      * Reverse the transformation of the point.
62      *
63      * @param view The bounding box of the view, in output-local
64      *   coordinates.
65      * @param point The point to untransform, in output-local coordinates.
66      *
67      * @return The point before after transforming it, in output-local
68      *   coordinates. If a reversal of the transformation is not possible,
69      *   return NaN.
70      */
71     virtual wf::pointf_t untransform_point(
72         wf::geometry_t view, wf::pointf_t point) = 0;
73 
74     /**
75      * Compute the bounding box of the given region after transforming it.
76      *
77      * @param view The bounding box of the view, in output-local
78      *   coordinates.
79      * @param region The region whose bounding box should be computed, in
80      *   output-local coordinates.
81      *
82      * @return The bounding box of region after transforming it, in
83      *   output-local coordinates.
84      */
85     virtual wlr_box get_bounding_box(wf::geometry_t view, wlr_box region);
86 
87     /**
88      * Render the indicated parts of the view.
89      *
90      * @param src_tex The texture of the view.
91      * @param src_box The bounding box of the view in output-local coordinates.
92      * @param damage The region to repaint, clipped to the view's bounds.
93      *   It is in output-local coordinates.
94      * @param target_fb The framebuffer to draw the view to. It's geometry
95      *   is in output-local coordinates.
96      *
97      * The default implementation of render_with_damage() will simply
98      * iterate over all rectangles in the damage region, apply framebuffer
99      * transform to it and then call render_box(). Plugins can override
100      * either of the functions.
101      */
102     virtual void render_with_damage(wf::texture_t src_tex, wlr_box src_box,
103         const wf::region_t& damage, const wf::framebuffer_t& target_fb);
104 
105     /** Same as render_with_damage(), but for a single rectangle of damage */
render_box(wf::texture_t src_tex,wlr_box src_box,wlr_box scissor_box,const wf::framebuffer_t & target_fb)106     virtual void render_box(wf::texture_t src_tex, wlr_box src_box,
107         wlr_box scissor_box, const wf::framebuffer_t& target_fb)
108     {}
109 
~view_transformer_t()110     virtual ~view_transformer_t()
111     {}
112 };
113 
114 /* 2D transforms operate with a coordinate system centered at the
115  * center of the main surface(the wayfire_view_t) */
116 class view_2D : public view_transformer_t
117 {
118   protected:
119     wayfire_view view;
120     const uint32_t z_order;
121 
122   public:
123     float angle = 0.0f;
124     float scale_x = 1.0f, scale_y = 1.0f;
125     float translation_x = 0.0f, translation_y = 0.0f;
126     float alpha = 1.0f;
127 
128   public:
129     view_2D(wayfire_view view, uint32_t z_order_ = TRANSFORMER_2D);
130 
get_z_order()131     virtual uint32_t get_z_order() override
132     {
133         return z_order;
134     }
135 
136     wf::pointf_t transform_point(
137         wf::geometry_t view, wf::pointf_t point) override;
138     wf::pointf_t untransform_point(
139         wf::geometry_t view, wf::pointf_t point) override;
140     void render_box(wf::texture_t src_tex, wlr_box src_box,
141         wlr_box scissor_box, const wf::framebuffer_t& target_fb) override;
142 };
143 
144 /* Those are centered relative to the view's bounding box */
145 class view_3D : public view_transformer_t
146 {
147   protected:
148     wayfire_view view;
149     const uint32_t z_order;
150 
151   public:
152     glm::mat4 view_proj{1.0}, translation{1.0}, rotation{1.0}, scaling{1.0};
153     glm::vec4 color{1, 1, 1, 1};
154 
155     glm::mat4 calculate_total_transform();
156 
157   public:
158     view_3D(wayfire_view view, uint32_t z_order_ = TRANSFORMER_3D);
159 
get_z_order()160     virtual uint32_t get_z_order() override
161     {
162         return z_order;
163     }
164 
165     wf::pointf_t transform_point(
166         wf::geometry_t view, wf::pointf_t point) override;
167     wf::pointf_t untransform_point(
168         wf::geometry_t view, wf::pointf_t point) override;
169     void render_box(wf::texture_t src_tex, wlr_box src_box,
170         wlr_box scissor_box, const wf::framebuffer_t& target_fb) override;
171 
172     static const float fov; // PI / 8
173     static glm::mat4 default_view_matrix();
174     static glm::mat4 default_proj_matrix();
175 };
176 
177 /* create a matrix which corresponds to the inverse of the given transform */
178 glm::mat4 get_output_matrix_from_transform(wl_output_transform transform);
179 
180 /* a matrix which can be used to render wf::geometry_t directly */
181 glm::mat4 output_get_projection(wf::output_t *output);
182 }
183 
184 #endif /* end of include guard: VIEW_TRANSFORM_HPP */
185