~ubuntu-branches/ubuntu/wily/mir/wily-proposed

« back to all changes in this revision

Viewing changes to src/platforms/android/server/display.cpp

  • Committer: Package Import Robot
  • Author(s): CI Train Bot
  • Date: 2015-05-12 13:12:55 UTC
  • mto: This revision was merged to the branch mainline in revision 96.
  • Revision ID: package-import@ubuntu.com-20150512131255-y7z12i8n4pbvo70x
Tags: upstream-0.13.0+15.10.20150512
ImportĀ upstreamĀ versionĀ 0.13.0+15.10.20150512

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
 
71
71
namespace
72
72
{
73
 
void safe_power_mode(mga::HwcConfiguration& config, MirPowerMode mode) noexcept
 
73
void power_mode(
 
74
    mga::DisplayName name,
 
75
    mga::HwcConfiguration& control,
 
76
    mg::DisplayConfigurationOutput& config,
 
77
    MirPowerMode intended_mode)
 
78
{
 
79
    if (config.power_mode != intended_mode)
 
80
    {
 
81
        control.power_mode(name, intended_mode);
 
82
        config.power_mode = intended_mode;
 
83
    }
 
84
}
 
85
 
 
86
void power_mode_safe(
 
87
    mga::DisplayName name,
 
88
    mga::HwcConfiguration& control,
 
89
    mg::DisplayConfigurationOutput& config,
 
90
    MirPowerMode intended_mode) noexcept
74
91
try
75
92
{
76
 
    config.power_mode(mga::DisplayName::primary, mode);
 
93
    power_mode(name, control, config, intended_mode);
77
94
} catch (...) {}
78
95
 
 
96
void set_powermode_all_displays(
 
97
    mga::HwcConfiguration& control,
 
98
    mga::DisplayConfiguration& config,
 
99
    MirPowerMode intended_mode) noexcept
 
100
{
 
101
    power_mode_safe(mga::DisplayName::primary, control, config.primary(), intended_mode);
 
102
    if (config.external().connected)
 
103
        power_mode_safe(mga::DisplayName::external, control, config.external(), intended_mode); 
 
104
}
 
105
 
79
106
std::unique_ptr<mga::ConfigurableDisplayBuffer> create_display_buffer(
 
107
    std::shared_ptr<mga::DisplayDevice> const& display_device,
 
108
    mga::DisplayName name,
80
109
    mga::DisplayComponentFactory& display_buffer_builder,
81
 
    mga::DisplayAttribs const& attribs,
 
110
    mg::DisplayConfigurationOutput const& config,
82
111
    std::shared_ptr<mg::GLProgramFactory> const& gl_program_factory,
83
112
    mga::PbufferGLContext const& gl_context,
84
113
    mga::OverlayOptimization overlay_option)
85
114
{
86
 
    std::shared_ptr<mga::FramebufferBundle> fbs{display_buffer_builder.create_framebuffers(attribs)};
 
115
    std::shared_ptr<mga::FramebufferBundle> fbs{display_buffer_builder.create_framebuffers(config)};
87
116
    auto cache = std::make_shared<mga::InterpreterCache>();
88
 
    auto interpreter = std::make_shared<mga::ServerRenderWindow>(fbs, cache);
 
117
    auto interpreter = std::make_shared<mga::ServerRenderWindow>(fbs, config.current_format, cache);
89
118
    auto native_window = std::make_shared<mga::MirNativeWindow>(interpreter);
90
119
    return std::unique_ptr<mga::ConfigurableDisplayBuffer>(new mga::DisplayBuffer(
 
120
        name,
91
121
        display_buffer_builder.create_layer_list(),
92
122
        fbs,
93
 
        display_buffer_builder.create_display_device(),
 
123
        display_device,
94
124
        native_window,
95
125
        gl_context,
96
126
        *gl_program_factory,
105
135
    std::shared_ptr<GLConfig> const& gl_config,
106
136
    std::shared_ptr<DisplayReport> const& display_report,
107
137
    mga::OverlayOptimization overlay_option) :
 
138
    display_report{display_report},
108
139
    display_buffer_builder{display_buffer_builder},
109
140
    hwc_config{display_buffer_builder->create_hwc_configuration()},
110
 
    hotplug_subscription{hwc_config->subscribe_to_config_changes(std::bind(&mga::Display::on_hotplug, this))},
111
 
    primary_attribs(hwc_config->active_attribs_for(mga::DisplayName::primary)),
 
141
    hotplug_subscription{hwc_config->subscribe_to_config_changes(
 
142
        std::bind(&mga::Display::on_hotplug, this),
 
143
        std::bind(&mga::Display::on_vsync, this, std::placeholders::_1))},
112
144
    config(
113
 
        primary_attribs,
114
 
        hwc_config->active_attribs_for(mga::DisplayName::external)),
115
 
    gl_context{config.primary_config().current_format, *gl_config, *display_report},
116
 
    display_buffer{create_display_buffer(
117
 
        *display_buffer_builder,
118
 
        primary_attribs,
119
 
        gl_program_factory,
120
 
        gl_context,
121
 
        overlay_option)},
122
 
    display_change_pipe(new DisplayChangePipe)
 
145
        hwc_config->active_config_for(mga::DisplayName::primary),
 
146
        mir_power_mode_off,
 
147
        hwc_config->active_config_for(mga::DisplayName::external),
 
148
        mir_power_mode_off),
 
149
    gl_context{config.primary().current_format, *gl_config, *display_report},
 
150
    display_device(display_buffer_builder->create_display_device()),
 
151
    display_change_pipe(new DisplayChangePipe),
 
152
    gl_program_factory(gl_program_factory),
 
153
    displays(
 
154
        display_device,
 
155
        create_display_buffer(
 
156
            display_device,
 
157
            mga::DisplayName::primary,
 
158
            *display_buffer_builder,
 
159
            config.primary(),
 
160
            gl_program_factory,
 
161
            gl_context,
 
162
            overlay_option))
123
163
{
124
164
    //Some drivers (depending on kernel state) incorrectly report an error code indicating that the display is already on. Ignore the first failure.
125
 
    safe_power_mode(*hwc_config, mir_power_mode_on);
 
165
    set_powermode_all_displays(*hwc_config, config, mir_power_mode_on);
 
166
 
 
167
    if (config.external().connected)
 
168
    {
 
169
        displays.add(mga::DisplayName::external,
 
170
            create_display_buffer(
 
171
                display_device,
 
172
                mga::DisplayName::external,
 
173
                *display_buffer_builder,
 
174
                config.external(),
 
175
                gl_program_factory,
 
176
                gl_context,
 
177
                mga::OverlayOptimization::disabled));
 
178
    }
126
179
 
127
180
    display_report->report_successful_setup_of_native_resources();
128
181
 
134
187
 
135
188
mga::Display::~Display() noexcept
136
189
{
137
 
    if (config.primary_config().power_mode != mir_power_mode_off)
138
 
        safe_power_mode(*hwc_config, mir_power_mode_off);
139
 
}
140
 
 
141
 
void mga::Display::for_each_display_buffer(std::function<void(mg::DisplayBuffer&)> const& f)
142
 
{
143
 
    std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
144
 
 
145
 
    if (config.primary_config().power_mode == mir_power_mode_on)
146
 
        f(*display_buffer);
147
 
}
148
 
 
149
 
std::unique_ptr<mg::DisplayConfiguration> mga::Display::configuration() const
150
 
{
151
 
    std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
 
190
    set_powermode_all_displays(*hwc_config, config, mir_power_mode_off);
 
191
}
 
192
 
 
193
void mga::Display::update_configuration(std::lock_guard<std::mutex> const&) const
 
194
{
152
195
    if (configuration_dirty)
153
196
    {
 
197
        auto external_config = hwc_config->active_config_for(mga::DisplayName::external);
 
198
        if (external_config.connected)
 
199
            power_mode(mga::DisplayName::external, *hwc_config, config.external(), mir_power_mode_on);
 
200
        else
 
201
            config.external().power_mode = mir_power_mode_off;
 
202
 
154
203
        config = mga::DisplayConfiguration(
155
 
            hwc_config->active_attribs_for(mga::DisplayName::primary),
156
 
            hwc_config->active_attribs_for(mga::DisplayName::external));
 
204
            hwc_config->active_config_for(mga::DisplayName::primary),
 
205
            config.primary().power_mode,
 
206
            std::move(external_config),
 
207
            config.external().power_mode);
157
208
        configuration_dirty = false;
158
209
    }
159
 
 
 
210
}
 
211
 
 
212
void mga::Display::for_each_display_sync_group(std::function<void(mg::DisplaySyncGroup&)> const& f)
 
213
{
 
214
    std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
 
215
    update_configuration(lock);
 
216
    if ((config.external().connected) && !displays.display_present(mga::DisplayName::external))
 
217
        displays.add(mga::DisplayName::external,
 
218
            create_display_buffer(
 
219
                display_device,
 
220
                mga::DisplayName::external,
 
221
                *display_buffer_builder,
 
222
                config.external(),
 
223
                gl_program_factory,
 
224
                gl_context,
 
225
                mga::OverlayOptimization::disabled));
 
226
    if ((!config.external().connected) && displays.display_present(mga::DisplayName::external))
 
227
        displays.remove(mga::DisplayName::external);
 
228
 
 
229
    f(displays);
 
230
}
 
231
 
 
232
std::unique_ptr<mg::DisplayConfiguration> mga::Display::configuration() const
 
233
{
 
234
    std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
 
235
    update_configuration(lock);
160
236
    return std::unique_ptr<mg::DisplayConfiguration>(new mga::DisplayConfiguration(config));
161
237
}
162
238
 
167
243
 
168
244
    std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
169
245
 
170
 
    new_configuration.for_each_output([this](mg::DisplayConfigurationOutput const& output) {
171
 
        //TODO: support configuring the external displaybuffer
172
 
        if (config.primary_config().id == output.id)
173
 
        {
174
 
            if (output.current_format != config[output.id].current_format)
175
 
                BOOST_THROW_EXCEPTION(std::logic_error("could not change display buffer format"));
176
 
 
177
 
            //TODO: We don't support rotation yet, so
178
 
            //we preserve this orientation change so the compositor can rotate everything in GL 
179
 
            config[output.id].orientation = output.orientation;
180
 
 
181
 
            if (output.power_mode != config[output.id].power_mode)
182
 
            {
183
 
                hwc_config->power_mode(mga::DisplayName::primary, output.power_mode);
184
 
                config[output.id].power_mode = output.power_mode;
185
 
            }
186
 
 
187
 
            display_buffer->configure(output.power_mode, output.orientation);
 
246
    new_configuration.for_each_output([this](mg::DisplayConfigurationOutput const& output)
 
247
    {
 
248
        if (output.current_format != config[output.id].current_format)
 
249
            BOOST_THROW_EXCEPTION(std::logic_error("could not change display buffer format"));
 
250
 
 
251
        config[output.id].orientation = output.orientation;
 
252
        if (config.primary().id == output.id)
 
253
        {
 
254
            power_mode(mga::DisplayName::primary, *hwc_config, config.primary(), output.power_mode);
 
255
            displays.configure(mga::DisplayName::primary, output.power_mode, output.orientation);
 
256
        }
 
257
        else if (config.external().connected)
 
258
        {
 
259
            power_mode(mga::DisplayName::external, *hwc_config, config.external(), output.power_mode);
 
260
            displays.configure(mga::DisplayName::external, output.power_mode, output.orientation);
188
261
        }
189
262
    });
190
263
}
191
264
 
192
 
//NOTE: We cannot call back to hwc from within the hotplug callback. Only arrange for an update.
 
265
//NOTE: We avoid calling back to hwc from within the hotplug callback. Only arrange for an update.
193
266
void mga::Display::on_hotplug()
194
267
{
195
268
    std::lock_guard<decltype(configuration_mutex)> lock{configuration_mutex};
197
270
    display_change_pipe->notify_change();
198
271
}
199
272
 
 
273
void mga::Display::on_vsync(DisplayName name) const
 
274
{
 
275
    display_report->report_vsync(name);
 
276
}
 
277
 
200
278
void mga::Display::register_configuration_change_handler(
201
279
    EventHandlerRegister& event_handler,
202
280
    DisplayConfigurationChangeHandler const& change_handler)