37
38
namespace geom = mir::geometry;
39
40
ms::BasicSurface::BasicSurface(
40
std::shared_ptr<SurfaceData> const& surface_data,
41
std::string const& name,
42
geometry::Rectangle rect,
43
std::function<void()> change_cb,
41
45
std::shared_ptr<mc::BufferStream> const& buffer_stream,
42
46
std::shared_ptr<input::InputChannel> const& input_channel,
43
47
std::shared_ptr<SceneReport> const& report) :
44
surface_data(surface_data),
48
notify_change(change_cb),
51
transformation_dirty(true),
53
first_frame_posted(false),
55
nonrectangular(nonrectangular),
56
input_rectangles{surface_rect},
45
57
surface_buffer_stream(buffer_stream),
46
58
server_input_channel(input_channel),
49
report->surface_created(this);
61
report->surface_created(this, surface_name);
52
64
void ms::BasicSurface::force_requests_to_complete()
64
76
return surface_buffer_stream;
67
std::shared_ptr<mc::CompositingCriteria> ms::BasicSurface::compositing_criteria()
72
79
std::string const& ms::BasicSurface::name() const
74
return surface_data->name();
77
84
void ms::BasicSurface::move_to(geometry::Point const& top_left)
79
surface_data->move_to(top_left);
82
void ms::BasicSurface::set_rotation(float degrees, glm::vec3 const& axis)
84
surface_data->apply_rotation(degrees, axis);
87
std::unique_lock<std::mutex> lk(guard);
88
surface_rect.top_left = top_left;
89
transformation_dirty = true;
87
94
float ms::BasicSurface::alpha() const
89
return surface_data->alpha();
92
void ms::BasicSurface::set_alpha(float alpha_v)
94
surface_data->apply_alpha(alpha_v);
96
std::unique_lock<std::mutex> lk(guard);
97
100
void ms::BasicSurface::set_hidden(bool hide)
99
surface_data->set_hidden(hide);
102
geom::Point ms::BasicSurface::top_left() const
104
return surface_data->position();
103
std::unique_lock<std::mutex> lk(guard);
107
109
mir::geometry::Size ms::BasicSurface::size() const
109
return surface_data->size();
111
std::unique_lock<std::mutex> lk(guard);
112
return surface_rect.size;
112
115
MirPixelFormat ms::BasicSurface::pixel_format() const
183
186
surface_buffer_stream->resize(size);
185
188
// Now the buffer stream has successfully resized, update the state second;
186
surface_data->resize(size);
190
std::unique_lock<std::mutex> lock(guard);
191
surface_rect.size = size;
192
transformation_dirty = true;
199
geom::Point ms::BasicSurface::top_left() const
201
std::unique_lock<std::mutex> lk(guard);
202
return surface_rect.top_left;
205
bool ms::BasicSurface::contains(geom::Point const& point) const
207
std::unique_lock<std::mutex> lock(guard);
211
for (auto const& rectangle : input_rectangles)
213
if (rectangle.contains(point))
221
void ms::BasicSurface::frame_posted()
224
std::unique_lock<std::mutex> lk(guard);
225
first_frame_posted = true;
230
void ms::BasicSurface::set_alpha(float alpha)
233
std::unique_lock<std::mutex> lk(guard);
234
surface_alpha = alpha;
240
void ms::BasicSurface::set_rotation(float degrees, glm::vec3 const& axis)
243
std::unique_lock<std::mutex> lk(guard);
244
rotation_matrix = glm::rotate(glm::mat4(1.0f), degrees, axis);
245
transformation_dirty = true;
250
glm::mat4 const& ms::BasicSurface::transformation() const
252
std::unique_lock<std::mutex> lk(guard);
254
auto surface_size = surface_rect.size;
255
auto surface_top_left = surface_rect.top_left;
256
if (transformation_dirty || transformation_size != surface_size)
258
const glm::vec3 top_left_vec{surface_top_left.x.as_int(),
259
surface_top_left.y.as_int(),
261
const glm::vec3 size_vec{surface_size.width.as_uint32_t(),
262
surface_size.height.as_uint32_t(),
265
/* Get the center of the renderable's area */
266
const glm::vec3 center_vec(top_left_vec + 0.5f * size_vec);
269
* Every renderable is drawn using a 1x1 quad centered at 0,0.
270
* We need to transform and scale that quad to get to its final position
273
* 1. We scale the quad vertices (from 1x1 to wxh)
274
* 2. We move the quad to its final position. Note that because the quad
275
* is centered at (0,0), we need to translate by center_vec, not
278
glm::mat4 pos_size_matrix;
279
pos_size_matrix = glm::translate(pos_size_matrix, center_vec);
280
pos_size_matrix = glm::scale(pos_size_matrix, size_vec);
282
// Rotate, then scale, then translate
283
transformation_matrix = pos_size_matrix * rotation_matrix;
284
transformation_size = surface_size;
285
transformation_dirty = false;
288
return transformation_matrix;
291
bool ms::BasicSurface::should_be_rendered_in(geom::Rectangle const& rect) const
293
std::unique_lock<std::mutex> lk(guard);
295
if (hidden || !first_frame_posted)
298
return rect.overlaps(surface_rect);
301
bool ms::BasicSurface::shaped() const
303
return nonrectangular;