~ubuntu-branches/ubuntu/utopic/mir/utopic-proposed

« back to all changes in this revision

Viewing changes to src/server/scene/basic_surface.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release
  • Date: 2014-03-10 19:28:46 UTC
  • mto: This revision was merged to the branch mainline in revision 63.
  • Revision ID: package-import@ubuntu.com-20140310192846-rq9qm3ec26yrelo2
Tags: upstream-0.1.6+14.04.20140310
ImportĀ upstreamĀ versionĀ 0.1.6+14.04.20140310

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright Ā© 2012 Canonical Ltd.
 
2
 * Copyright Ā© 2012-2014 Canonical Ltd.
3
3
 *
4
4
 * This program is free software: you can redistribute it and/or modify it
5
5
 * under the terms of the GNU General Public License version 3,
19
19
 */
20
20
 
21
21
#include "basic_surface.h"
22
 
#include "surface_data.h"
23
22
#include "mir/compositor/buffer_stream.h"
24
23
#include "mir/input/input_channel.h"
25
24
#include "mir/graphics/buffer.h"
26
25
 
27
26
#include "mir/scene/scene_report.h"
28
27
 
 
28
#include <glm/gtc/matrix_transform.hpp>
 
29
 
29
30
#include <boost/throw_exception.hpp>
30
31
 
31
32
#include <stdexcept>
37
38
namespace geom = mir::geometry;
38
39
 
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,
 
44
    bool nonrectangular,
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),
 
49
    surface_name(name),
 
50
    surface_rect(rect),
 
51
    transformation_dirty(true),
 
52
    surface_alpha(1.0f),
 
53
    first_frame_posted(false),
 
54
    hidden(false),
 
55
    nonrectangular(nonrectangular),
 
56
    input_rectangles{surface_rect},
45
57
    surface_buffer_stream(buffer_stream),
46
58
    server_input_channel(input_channel),
47
59
    report(report)
48
60
{
49
 
    report->surface_created(this);
 
61
    report->surface_created(this, surface_name);
50
62
}
51
63
 
52
64
void ms::BasicSurface::force_requests_to_complete()
54
66
    surface_buffer_stream->force_requests_to_complete();
55
67
}
56
68
 
57
 
ms::BasicSurface::~BasicSurface()
 
69
ms::BasicSurface::~BasicSurface() noexcept
58
70
{
59
 
    report->surface_deleted(this);
 
71
    report->surface_deleted(this, surface_name);
60
72
}
61
73
 
62
74
std::shared_ptr<mc::BufferStream> ms::BasicSurface::buffer_stream() const
64
76
    return surface_buffer_stream;
65
77
}
66
78
 
67
 
std::shared_ptr<mc::CompositingCriteria> ms::BasicSurface::compositing_criteria()
68
 
{
69
 
    return surface_data;
70
 
}
71
 
 
72
79
std::string const& ms::BasicSurface::name() const
73
80
{
74
 
    return surface_data->name();
 
81
    return surface_name;
75
82
}
76
83
 
77
84
void ms::BasicSurface::move_to(geometry::Point const& top_left)
78
85
{
79
 
    surface_data->move_to(top_left);
80
 
}
81
 
 
82
 
void ms::BasicSurface::set_rotation(float degrees, glm::vec3 const& axis)
83
 
{
84
 
    surface_data->apply_rotation(degrees, axis);
 
86
    {
 
87
        std::unique_lock<std::mutex> lk(guard);
 
88
        surface_rect.top_left = top_left;
 
89
        transformation_dirty = true;
 
90
    }
 
91
    notify_change();
85
92
}
86
93
 
87
94
float ms::BasicSurface::alpha() const
88
95
{
89
 
    return surface_data->alpha();
90
 
}
91
 
 
92
 
void ms::BasicSurface::set_alpha(float alpha_v)
93
 
{
94
 
    surface_data->apply_alpha(alpha_v);
 
96
    std::unique_lock<std::mutex> lk(guard);
 
97
    return surface_alpha;
95
98
}
96
99
 
97
100
void ms::BasicSurface::set_hidden(bool hide)
98
101
{
99
 
    surface_data->set_hidden(hide);
100
 
}
101
 
 
102
 
geom::Point ms::BasicSurface::top_left() const
103
 
{
104
 
    return surface_data->position();
 
102
    {
 
103
        std::unique_lock<std::mutex> lk(guard);
 
104
        hidden = hide;
 
105
    }
 
106
    notify_change();
105
107
}
106
108
 
107
109
mir::geometry::Size ms::BasicSurface::size() const
108
110
{
109
 
    return surface_data->size();
 
111
    std::unique_lock<std::mutex> lk(guard);
 
112
    return surface_rect.size;
110
113
}
111
114
 
112
115
MirPixelFormat ms::BasicSurface::pixel_format() const
122
125
 
123
126
    if (posting)
124
127
    {
125
 
        surface_data->frame_posted();
 
128
        {
 
129
            std::unique_lock<std::mutex> lk(guard);
 
130
            first_frame_posted = true;
 
131
        }
 
132
        notify_change();
126
133
    }
127
134
}
128
135
 
155
162
    return server_input_channel;
156
163
}
157
164
 
158
 
std::shared_ptr<mi::Surface> ms::BasicSurface::input_surface() const
159
 
{
160
 
    return surface_data;
161
 
}
162
 
 
163
165
void ms::BasicSurface::set_input_region(std::vector<geom::Rectangle> const& input_rectangles)
164
166
{
165
 
    surface_data->set_input_region(input_rectangles);
 
167
    std::unique_lock<std::mutex> lock(guard);
 
168
    this->input_rectangles = input_rectangles;
166
169
}
167
170
 
168
171
bool ms::BasicSurface::resize(geom::Size const& size)
183
186
    surface_buffer_stream->resize(size);
184
187
 
185
188
    // Now the buffer stream has successfully resized, update the state second;
186
 
    surface_data->resize(size);
 
189
    {
 
190
        std::unique_lock<std::mutex> lock(guard);
 
191
        surface_rect.size = size;
 
192
        transformation_dirty = true;
 
193
    }
 
194
    notify_change();
187
195
 
188
196
    return true;
189
197
}
 
198
 
 
199
geom::Point ms::BasicSurface::top_left() const
 
200
{
 
201
    std::unique_lock<std::mutex> lk(guard);
 
202
    return surface_rect.top_left;
 
203
}
 
204
 
 
205
bool ms::BasicSurface::contains(geom::Point const& point) const
 
206
{
 
207
    std::unique_lock<std::mutex> lock(guard);
 
208
    if (hidden)
 
209
        return false;
 
210
 
 
211
    for (auto const& rectangle : input_rectangles)
 
212
    {
 
213
        if (rectangle.contains(point))
 
214
        {
 
215
            return true;
 
216
        }
 
217
    }
 
218
    return false;
 
219
}
 
220
 
 
221
void ms::BasicSurface::frame_posted()
 
222
{
 
223
    {
 
224
        std::unique_lock<std::mutex> lk(guard);
 
225
        first_frame_posted = true;
 
226
    }
 
227
    notify_change();
 
228
}
 
229
 
 
230
void ms::BasicSurface::set_alpha(float alpha)
 
231
{
 
232
    {
 
233
        std::unique_lock<std::mutex> lk(guard);
 
234
        surface_alpha = alpha;
 
235
    }
 
236
    notify_change();
 
237
}
 
238
 
 
239
 
 
240
void ms::BasicSurface::set_rotation(float degrees, glm::vec3 const& axis)
 
241
{
 
242
    {
 
243
        std::unique_lock<std::mutex> lk(guard);
 
244
        rotation_matrix = glm::rotate(glm::mat4(1.0f), degrees, axis);
 
245
        transformation_dirty = true;
 
246
    }
 
247
    notify_change();
 
248
}
 
249
 
 
250
glm::mat4 const& ms::BasicSurface::transformation() const
 
251
{
 
252
    std::unique_lock<std::mutex> lk(guard);
 
253
 
 
254
    auto surface_size = surface_rect.size;
 
255
    auto surface_top_left = surface_rect.top_left;
 
256
    if (transformation_dirty || transformation_size != surface_size)
 
257
    {
 
258
        const glm::vec3 top_left_vec{surface_top_left.x.as_int(),
 
259
                                     surface_top_left.y.as_int(),
 
260
                                     0.0f};
 
261
        const glm::vec3 size_vec{surface_size.width.as_uint32_t(),
 
262
                                 surface_size.height.as_uint32_t(),
 
263
                                 0.0f};
 
264
 
 
265
        /* Get the center of the renderable's area */
 
266
        const glm::vec3 center_vec(top_left_vec + 0.5f * size_vec);
 
267
 
 
268
        /*
 
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
 
271
         * and size.
 
272
         *
 
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
 
276
         *    top_left_vec.
 
277
         */
 
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);
 
281
 
 
282
        // Rotate, then scale, then translate
 
283
        transformation_matrix = pos_size_matrix * rotation_matrix;
 
284
        transformation_size = surface_size;
 
285
        transformation_dirty = false;
 
286
    }
 
287
 
 
288
    return transformation_matrix;
 
289
}
 
290
 
 
291
bool ms::BasicSurface::should_be_rendered_in(geom::Rectangle const& rect) const
 
292
{
 
293
    std::unique_lock<std::mutex> lk(guard);
 
294
 
 
295
    if (hidden || !first_frame_posted)
 
296
        return false;
 
297
 
 
298
    return rect.overlaps(surface_rect);
 
299
}
 
300
 
 
301
bool ms::BasicSurface::shaped() const
 
302
{
 
303
    return nonrectangular;
 
304
}