2 * Copyright (C) 2017 Simon Fels <morphis@gravedo.de>
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 3, as published
6 * by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranties of
10 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 * PURPOSE. See the GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include "anbox/graphics/multi_window_composer_strategy.h"
19 #include "anbox/wm/manager.h"
20 #include "anbox/utils.h"
24 MultiWindowComposerStrategy::MultiWindowComposerStrategy(const std::shared_ptr<wm::Manager> &wm) : wm_(wm) {}
26 std::map<std::shared_ptr<wm::Window>, RenderableList> MultiWindowComposerStrategy::process_layers(const RenderableList &renderables) {
27 WindowRenderableList win_layers;
28 for (const auto &renderable : renderables) {
29 // Ignore all surfaces which are not meant for a task
30 if (!utils::string_starts_with(renderable.name(), "org.anbox.surface."))
33 wm::Task::Id task_id = 0;
34 if (sscanf(renderable.name().c_str(), "org.anbox.surface.%d", &task_id) != 1 || !task_id)
37 auto w = wm_->find_window_for_task(task_id);
40 if (win_layers.find(w) == win_layers.end()) {
41 win_layers.insert({w, {renderable}});
45 win_layers[w].push_back(renderable);
48 for (auto &w : win_layers) {
49 const auto &renderables = w.second;
50 RenderableList final_renderables;
51 auto new_window_frame = Rect::Invalid;
52 auto max_layer_area = -1;
54 for (auto &r : renderables) {
55 const auto layer_area = r.screen_position().width() * r.screen_position().height();
56 // We always prioritize layers which are lower in the list we got
57 // from SurfaceFlinger as they are already ordered.
58 if (layer_area < max_layer_area)
61 max_layer_area = layer_area;
62 new_window_frame = r.screen_position();
65 for (auto &r : renderables) {
66 // As we get absolute display coordinates from the Android hwcomposer we
67 // need to recalculate all layer coordinates into relatives ones to the
68 // window they are drawn into.
70 r.screen_position().left() - new_window_frame.left() + r.crop().left(),
71 r.screen_position().top() - new_window_frame.top() + r.crop().top(),
72 r.screen_position().right() - new_window_frame.left() + r.crop().left(),
73 r.screen_position().bottom() - new_window_frame.top() + r.crop().top()};
75 auto new_renderable = r;
76 new_renderable.set_screen_position(rect);
77 final_renderables.push_back(new_renderable);
80 w.second = final_renderables;
85 } // namespace graphics