X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Fmulti_window_composer_strategy.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Fmulti_window_composer_strategy.cpp;h=0c58f97d18adc48ea81a17aa15647ecf370aa848;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/multi_window_composer_strategy.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/multi_window_composer_strategy.cpp new file mode 100644 index 0000000..0c58f97 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/multi_window_composer_strategy.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2017 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#include "anbox/graphics/multi_window_composer_strategy.h" +#include "anbox/wm/manager.h" +#include "anbox/utils.h" + +namespace anbox { +namespace graphics { +MultiWindowComposerStrategy::MultiWindowComposerStrategy(const std::shared_ptr &wm) : wm_(wm) {} + +std::map, RenderableList> MultiWindowComposerStrategy::process_layers(const RenderableList &renderables) { + WindowRenderableList win_layers; + for (const auto &renderable : renderables) { + // Ignore all surfaces which are not meant for a task + if (!utils::string_starts_with(renderable.name(), "org.anbox.surface.")) + continue; + + wm::Task::Id task_id = 0; + if (sscanf(renderable.name().c_str(), "org.anbox.surface.%d", &task_id) != 1 || !task_id) + continue; + + auto w = wm_->find_window_for_task(task_id); + if (!w) continue; + + if (win_layers.find(w) == win_layers.end()) { + win_layers.insert({w, {renderable}}); + continue; + } + + win_layers[w].push_back(renderable); + } + + for (auto &w : win_layers) { + const auto &renderables = w.second; + RenderableList final_renderables; + auto new_window_frame = Rect::Invalid; + auto max_layer_area = -1; + + for (auto &r : renderables) { + const auto layer_area = r.screen_position().width() * r.screen_position().height(); + // We always prioritize layers which are lower in the list we got + // from SurfaceFlinger as they are already ordered. + if (layer_area < max_layer_area) + continue; + + max_layer_area = layer_area; + new_window_frame = r.screen_position(); + } + + for (auto &r : renderables) { + // As we get absolute display coordinates from the Android hwcomposer we + // need to recalculate all layer coordinates into relatives ones to the + // window they are drawn into. + auto rect = Rect{ + r.screen_position().left() - new_window_frame.left() + r.crop().left(), + r.screen_position().top() - new_window_frame.top() + r.crop().top(), + r.screen_position().right() - new_window_frame.left() + r.crop().left(), + r.screen_position().bottom() - new_window_frame.top() + r.crop().top()}; + + auto new_renderable = r; + new_renderable.set_screen_position(rect); + final_renderables.push_back(new_renderable); + } + + w.second = final_renderables; + } + + return win_layers; +} +} // namespace graphics +} // namespace anbox