~dandrader/mir/cross-compile-parallel

« back to all changes in this revision

Viewing changes to src/server/graphics/nested/nested_display.cpp

  • Committer: Daniel van Vugt
  • Date: 2013-08-28 03:41:48 UTC
  • mfrom: (1026 trunk)
  • mto: This revision was merged to the branch mainline in revision 1040.
  • Revision ID: daniel.van.vugt@canonical.com-20130828034148-3rie198rwv3qmnhz
MergeĀ latestĀ lp:mir

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
 
35
35
namespace
36
36
{
37
 
auto configure_outputs(MirConnection* connection)
38
 
-> std::unordered_map<uint32_t, std::shared_ptr<mgn::detail::NestedOutput>>
39
 
{
40
 
    // TODO for proper mirrored mode support we will need to detect overlapping outputs and
41
 
    // TODO only use a single surface for them. The OverlappingOutputGrouping utility class
42
 
    // TODO used by the GBM backend for a similar purpose could help with this.
43
 
 
44
 
    mgnw::MirDisplayConfigHandle display_config{connection};
45
 
 
46
 
    std::unordered_map<uint32_t, std::shared_ptr<mgn::detail::NestedOutput>> result;
47
 
 
48
 
    for (decltype(display_config->num_outputs) i = 0; i != display_config->num_outputs; ++i)
49
 
    {
50
 
        auto const egl_display_info = display_config->outputs+i;
51
 
 
52
 
        if (egl_display_info->used)
53
 
        {
54
 
            result[egl_display_info->output_id] =
55
 
                std::make_shared<mgn::detail::NestedOutput>(connection, egl_display_info);
56
 
        }
57
 
    }
58
 
 
59
 
    return result;
60
 
}
61
 
 
62
37
EGLint const egl_attribs[] = {
63
38
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
64
39
    EGL_RED_SIZE, 8,
76
51
}
77
52
 
78
53
 
79
 
mgn::detail::MirSurfaceHandle::MirSurfaceHandle(MirConnection* connection, MirDisplayOutput* const egl_display_info)
 
54
mgn::detail::MirSurfaceHandle::MirSurfaceHandle(MirConnection* connection, DisplayConfigurationOutput const& output)
80
55
{
81
 
    auto const egl_display_mode = egl_display_info->modes + egl_display_info->current_mode;
82
 
    auto const egl_display_format = egl_display_info->output_formats[egl_display_info->current_output_format];
 
56
    auto const& egl_display_mode = output.modes[output.current_mode_index];
 
57
    auto const egl_display_format = output.pixel_formats[output.current_format_index];
83
58
 
84
59
    MirSurfaceParameters const request_params =
85
60
        {
86
61
            "Mir nested display",
87
 
            int(egl_display_mode->horizontal_resolution),
88
 
            int(egl_display_mode->vertical_resolution),
89
 
            egl_display_format,
 
62
            egl_display_mode.size.width.as_int(),
 
63
            egl_display_mode.size.height.as_int(),
 
64
            MirPixelFormat(egl_display_format),
90
65
            mir_buffer_usage_hardware,
91
 
            egl_display_info->output_id
 
66
            static_cast<uint32_t>(output.id.as_value())
92
67
        };
93
68
 
94
69
    mir_surface = mir_connection_create_surface_sync(connection, &request_params);
161
136
    if (!display_handles.fetch_add(-1)) eglTerminate(egl_display);
162
137
}
163
138
 
164
 
mgn::detail::NestedOutput::NestedOutput(MirConnection* connection, MirDisplayOutput* const egl_display_info) :
165
 
    mir_surface(connection, egl_display_info),
 
139
mgn::detail::NestedOutput::NestedOutput(MirConnection* connection, DisplayConfigurationOutput const& output) :
 
140
    mir_surface(connection, output),
166
141
    egl_display{connection},
167
142
    egl_config{(egl_display.initialize(), egl_display.choose_config(egl_attribs))},
168
143
    egl_surface{egl_display, egl_display.egl_surface(egl_config, mir_surface)},
180
155
mgn::NestedDisplay::NestedDisplay(MirConnection* connection, std::shared_ptr<mg::DisplayReport> const& display_report) :
181
156
    connection{connection},
182
157
    display_report{display_report},
183
 
    outputs{configure_outputs(connection)}
 
158
    outputs{}
184
159
{
185
 
    if (outputs.empty())
186
 
        BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir needs at least one output for display"));
 
160
    configure(*configuration());
187
161
}
188
162
 
189
163
mgn::NestedDisplay::~NestedDisplay() noexcept
202
176
 
203
177
void mgn::NestedDisplay::configure(mg::DisplayConfiguration const& configuration)
204
178
{
 
179
    decltype(outputs) result;
 
180
 
 
181
    // TODO for proper mirrored mode support we will need to detect overlapping outputs and
 
182
    // TODO only use a single surface for them. The OverlappingOutputGrouping utility class
 
183
    // TODO used by the GBM backend for a similar purpose could help with this.
 
184
    configuration.for_each_output(
 
185
        [&](mg::DisplayConfigurationOutput const& output)
 
186
        {
 
187
            if (output.used)
 
188
            {
 
189
                result[output.id] = std::make_shared<mgn::detail::NestedOutput>(connection, output);
 
190
            }
 
191
        });
 
192
 
 
193
    if (result.empty())
 
194
        BOOST_THROW_EXCEPTION(std::runtime_error("Nested Mir needs at least one output for display"));
 
195
 
205
196
    auto const& conf = dynamic_cast<NestedDisplayConfiguration const&>(configuration);
206
197
 
 
198
    outputs.swap(result);
207
199
    mir_connection_apply_display_config(connection, conf);
208
200
}
209
201
 
 
202
namespace
 
203
{
 
204
void display_config_callback_thunk(MirConnection* /*connection*/, void* callback)
 
205
{
 
206
    (*static_cast<mg::DisplayConfigurationChangeHandler*>(callback))();
 
207
}
 
208
}
 
209
 
210
210
void mgn::NestedDisplay::register_configuration_change_handler(
211
211
        EventHandlerRegister& /*handlers*/,
212
 
        DisplayConfigurationChangeHandler const& /*conf_change_handler*/)
 
212
        DisplayConfigurationChangeHandler const& conf_change_handler)
213
213
{
214
 
    // TODO need to watch for changes via mir_connection_set_display_config_change_callback()
215
 
    // TODO and invoke conf_change_handler() (I don't think we need handlers)
 
214
    mir_connection_set_display_config_change_callback(
 
215
        connection,
 
216
        &display_config_callback_thunk,
 
217
        &(my_conf_change_handler = conf_change_handler));
216
218
}
217
219
 
218
220
void mgn::NestedDisplay::register_pause_resume_handlers(