2
* Copyright © 2016 Canonical Ltd.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 or 3 as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
16
* Authored by: Alan Griffiths <alan@octopull.co.uk>
19
#include "sw_splash.h"
21
#include <mir/client/display_config.h>
22
#include <mir/client/surface.h>
23
#include <mir/client/window.h>
24
#include <mir/client/window_spec.h>
26
#include <mir_toolkit/mir_buffer_stream.h>
35
MirPixelFormat find_8888_format(MirConnection* connection)
37
unsigned int const num_formats = 32;
38
MirPixelFormat pixel_formats[num_formats];
39
unsigned int valid_formats;
40
mir_connection_get_available_surface_formats(connection, pixel_formats, num_formats, &valid_formats);
42
for (unsigned int i = 0; i < num_formats; ++i)
44
MirPixelFormat cur_pf = pixel_formats[i];
45
if (cur_pf == mir_pixel_format_abgr_8888 ||
46
cur_pf == mir_pixel_format_argb_8888)
52
for (unsigned int i = 0; i < num_formats; ++i)
54
MirPixelFormat cur_pf = pixel_formats[i];
55
if (cur_pf == mir_pixel_format_xbgr_8888 ||
56
cur_pf == mir_pixel_format_xrgb_8888)
62
return *pixel_formats;
65
auto create_window(MirConnection* connection, mir::client::Surface const& surface) -> mir::client::Window
71
mir::client::DisplayConfig{connection}.for_each_output([&](MirOutput const* output)
73
if (mir_output_get_connection_state(output) == mir_output_connection_state_connected &&
74
mir_output_is_enabled(output))
76
id = mir_output_get_id(output);
78
MirOutputMode const* mode = mir_output_get_current_mode(output);
79
width = mir_output_mode_get_width(mode);
80
height = mir_output_mode_get_height(mode);
84
return mir::client::WindowSpec::for_normal_window(connection, width, height)
86
.set_fullscreen_on_output(id)
87
.add_surface(surface, width, height, 0, 0)
91
void render_pattern(MirGraphicsRegion *region, uint8_t pattern[])
93
char *row = region->vaddr;
95
for (int j = 0; j < region->height; j++)
97
uint32_t *pixel = (uint32_t*)row;
99
for (int i = 0; i < region->width; i++)
100
memcpy(pixel+i, pattern, sizeof pixel[i]);
102
row += region->stride;
107
struct SwSplash::Self
110
std::weak_ptr<mir::scene::Session> session;
113
SwSplash::SwSplash() : self{std::make_shared<Self>()} {}
115
SwSplash::~SwSplash() = default;
117
void SwSplash::operator()(std::weak_ptr<mir::scene::Session> const& session)
119
std::lock_guard<decltype(self->mutex)> lock{self->mutex};
120
self->session = session;
123
auto SwSplash::session() const -> std::weak_ptr<mir::scene::Session>
125
std::lock_guard<decltype(self->mutex)> lock{self->mutex};
126
return self->session;
129
void SwSplash::operator()(MirConnection* connection)
131
MirPixelFormat pixel_format = find_8888_format(connection);
133
uint8_t pattern[4] = { 0x14, 0x48, 0xDD, 0xFF };
137
case mir_pixel_format_abgr_8888:
138
case mir_pixel_format_xbgr_8888:
139
std::swap(pattern[2],pattern[0]);
142
case mir_pixel_format_argb_8888:
143
case mir_pixel_format_xrgb_8888:
151
mir::client::Surface surface{mir_connection_create_render_surface_sync(connection, 42, 42)};
152
MirBufferStream* buffer_stream = mir_render_surface_get_buffer_stream(surface, 42, 42, pixel_format);
154
auto const window = create_window(connection, surface);
156
MirGraphicsRegion graphics_region;
158
auto const time_limit = std::chrono::steady_clock::now() + std::chrono::seconds(2);
162
mir_buffer_stream_get_graphics_region(buffer_stream, &graphics_region);
164
render_pattern(&graphics_region, pattern);
165
mir_buffer_stream_swap_buffers_sync(buffer_stream);
167
for (auto& x : pattern)
170
std::this_thread::sleep_for(std::chrono::milliseconds(200));
172
while (std::chrono::steady_clock::now() < time_limit);