提交 a5e5d482 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!99 window & renderer solve problem

Merge pull request !99 from Night/master
......@@ -48,51 +48,60 @@ std::map<std::shared_ptr<wm::Window>, RenderableList> MultiWindowComposerStrateg
for (auto &w : win_layers) {
const auto &renderables = w.second;
RenderableList final_renderables;
int top = 1080;
int left = 1920;
for (auto &r : renderables) {
// We always prioritize layers which are lower in the list we got
// from SurfaceFlinger as they are already ordered.
int current_left = r.screen_position().left();
int current_top = r.screen_position().top();
int half_diff = 2;
if (r.screen_position().width() > w.first->frame().width()) {
auto diff = r.screen_position().width() - w.first->frame().width();
current_left += diff / half_diff;
}
if (r.screen_position().height() > w.first->frame().height()) {
auto diff = r.screen_position().height() - w.first->frame().height();
current_top += diff / half_diff;
}
if (current_left < left) {
left = current_left;
}
if (current_top < top) {
top = current_top;
}
}
auto window_frame = w.first->frame();
bool resizeable = w.first->checkResizeable();
auto old_frame = w.first->last_frame();
int max_area = 0;
Rect max_rect;
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() - left + r.crop().left(),
r.screen_position().top() - top + r.crop().top(),
r.screen_position().right() - left + r.crop().left(),
r.screen_position().bottom() - top + r.crop().top()};
r.screen_position().left() - window_frame.left(),
r.screen_position().top() - window_frame.top(),
r.screen_position().right() - window_frame.left(),
r.screen_position().bottom() - window_frame.top()};
if (rect.width() * rect.height() > max_area) {
max_area = rect.width() * rect.height();
max_rect = Rect(r.screen_position().left() - old_frame.left(),
r.screen_position().top() - old_frame.top(),
r.screen_position().right() - old_frame.left(),
r.screen_position().bottom() - old_frame.top());
}
auto new_renderable = r;
new_renderable.set_screen_position(rect);
final_renderables.push_back(new_renderable);
}
w.second = final_renderables;
}
bool changed = false;
if (resizeable) {
int max_old_area = 0;
Rect max_old_rect;
auto it = last_renderables.find(w.first);
if (it != last_renderables.end()) {
for (auto &rt : it->second) {
if (max_old_area < rt.screen_position().width() * rt.screen_position().height()) {
max_old_area = rt.screen_position().width() * rt.screen_position().height();
max_old_rect = rt.screen_position();
}
}
}
if (max_old_rect == max_rect) {
w.second = it->second;
changed = true;
} else {
w.first->setResizing(false);
}
}
return win_layers;
if(!changed) {
w.second = final_renderables;
}
}
last_renderables.swap(win_layers);
return last_renderables;
}
} // namespace graphics
} // namespace anbox
......@@ -33,6 +33,7 @@ class MultiWindowComposerStrategy : public LayerComposer::Strategy {
private:
std::shared_ptr<wm::Manager> wm_;
WindowRenderableList last_renderables;
};
} // namespace graphics
} // namespace anbox
......
......@@ -175,7 +175,7 @@ SDL_HitTestResult Window::on_window_hit(SDL_Window *window, const SDL_Point *pt,
SDL_HitTestResult result = SDL_HITTEST_NORMAL;
if (pt->y < top_drag_area_height) {
if (pt->y <= top_drag_area_height) {
if (!platform_window->initialized.load()) {
INFO("window initialized by click top");
platform_window->initialized = true;
......@@ -279,11 +279,19 @@ void Window::process_event(const SDL_Event &event) {
// SDL_WINDOWEVENT_SIZE_CHANGED is always sent.
case SDL_WINDOWEVENT_SIZE_CHANGED:
if (observer_) {
struct timeval now = (struct timeval) { 0 };
gettimeofday(&now, NULL);
last_resize_time_ = USEC_PER_SEC * (now.tv_sec) + now.tv_usec;
resizing_ = true;
observer_->window_resized(id_, event.window.data1, event.window.data2);
}
break;
case SDL_WINDOWEVENT_MOVED:
if (observer_) {
struct timeval now = (struct timeval) { 0 };
gettimeofday(&now, NULL);
last_resize_time_ = USEC_PER_SEC * (now.tv_sec) + now.tv_usec;
resizing_ = true;
observer_->window_moved(id_, event.window.data1, event.window.data2);
}
break;
......@@ -305,6 +313,22 @@ Window::Id Window::id() const { return id_; }
std::uint32_t Window::window_id() const { return SDL_GetWindowID(window_); }
bool Window::checkResizeable() {
struct timeval now = (struct timeval) { 0 };
gettimeofday(&now, NULL);
long long time_now = USEC_PER_SEC * (now.tv_sec) + now.tv_usec;
if (resizing_ && time_now - last_resize_time_ > RESIZE_TIMESPAN) {
last_frame_ = frame();
resizing_ = false;
}
return resizing_;
}
void Window::setResizing(bool resizing) {
last_frame_ = frame();
resizing_ = resizing;
}
void Window::update_state(const wm::WindowState::List &states) {
if (!initialized.load() && !states.empty()) {
int w = 0;
......@@ -330,7 +354,6 @@ void Window::update_state(const wm::WindowState::List &states) {
y == rect.top()) {
return;
}
struct timeval now = (struct timeval) { 0 };
gettimeofday(&now, NULL);
long long current_time = USEC_PER_SEC * (now.tv_sec) + now.tv_usec;
......
......@@ -41,6 +41,7 @@ class Window : public std::enable_shared_from_this<Window>, public wm::Window {
static const long long USEC_PER_SEC = 1000000;
static const long long APP_START_MAX_TIME = 15 * USEC_PER_SEC;
static const long long timespan_db_click = 500000;
static const long long RESIZE_TIMESPAN = USEC_PER_SEC / 2;
struct mini_size {
int minimum_width;
......@@ -77,6 +78,8 @@ class Window : public std::enable_shared_from_this<Window>, public wm::Window {
void update_state(const wm::WindowState::List &states) override;
bool check_db_clicked(int x, int y);
bool checkResizeable() override;
void setResizing(bool resizing) override;
void restore_window();
Id id() const;
......@@ -93,6 +96,7 @@ class Window : public std::enable_shared_from_this<Window>, public wm::Window {
std::atomic<bool> initialized{false};
long long last_update_time{ 0 };
long long last_resize_time_{ 0 };
Id id_;
std::shared_ptr<Observer> observer_;
EGLNativeDisplayType native_display_;
......
......@@ -21,8 +21,9 @@
namespace anbox {
namespace wm {
Window::Window(const std::shared_ptr<Renderer> &renderer, const Task::Id &task, const graphics::Rect &frame, const std::string &title)
: renderer_(renderer), task_(task), frame_(frame), title_(title), native_window_(0) {}
Window::Window(const std::shared_ptr<Renderer> &renderer, const Task::Id &task,
const graphics::Rect &frame, const std::string &title)
: renderer_(renderer), task_(task), frame_(frame), title_(title), native_window_(0), last_frame_(frame) {}
Window::~Window() {
release();
......@@ -44,6 +45,8 @@ Task::Id Window::task() const { return task_; }
graphics::Rect Window::frame() const { return frame_; }
graphics::Rect Window::last_frame() const { return last_frame_; }
EGLNativeWindowType Window::native_handle() const { return native_window_; }
std::string Window::title() const { return title_; }
......
......@@ -53,15 +53,21 @@ class Window {
virtual void update_state(const WindowState::List &states);
void update_frame(const graphics::Rect &frame);
void update_last_frame(const graphics::Rect &frame);
virtual bool title_event_filter(int y);
void set_native_handle(const EGLNativeWindowType &handle);
EGLNativeWindowType native_handle() const;
graphics::Rect frame() const;
graphics::Rect last_frame() const;
Task::Id task() const;
std::string title() const;
virtual bool checkResizeable() { return resizing_; }
virtual void setResizing(bool resizing) { resizing_ = resizing; }
protected:
graphics::Rect last_frame_;
bool resizing_{false};
private:
EGLNativeWindowType native_window_;
std::shared_ptr<Renderer> renderer_;
......
......@@ -125,7 +125,7 @@ TEST(LayerComposer, MapsLayersToWindows) {
};
RenderableList second_window_renderables{
{"org.anbox.surface.2", 1, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
{"org.anbox.surface.2", 1, 1.0f, {-300, -400, 724, 368}, {0, 0, 1024, 768}},
};
EXPECT_CALL(*renderer, draw(_, Rect{0, 0, first_window.frame().width(),
......@@ -171,12 +171,12 @@ TEST(LayerComposer, WindowPartiallyOffscreen) {
// but the layer covering the whole window is placed with its top left
// origin outside of the visible display area.
RenderableList renderables = {
{"org.anbox.surface.1", 0, 1.0f, {-100, -100, 924, 668}, {0, 0, 1024, 768}},
{"org.anbox.surface.1", 0, 1.0f, {0, 0, 924, 668}, {100, 100, 1024, 768}},
{"org.anbox.surface.1", 1, 1.0f, {0, 0, 100, 200}, {0, 0, 100, 200}},
};
RenderableList expected_renderables{
{"org.anbox.surface.1", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
{"org.anbox.surface.1", 0, 1.0f, {100, 100, 1024, 768}, {100, 100, 1024, 768}},
{"org.anbox.surface.1", 1, 1.0f, {100, 100, 200, 300}, {0, 0, 100, 200}},
};
......@@ -227,8 +227,8 @@ TEST(LayerComposer, PopupShouldNotCauseWindowLayerOffset) {
};
RenderableList expected_renderables{
{"org.anbox.surface.3", 0, 1.0f, {0, 24, 1024, 792}, {0, 0, 1024, 768}},
{"org.anbox.surface.3", 1, 1.0f, {784, 0, 1044, 160}, {0, 0, 260, 160}},
{"org.anbox.surface.3", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
{"org.anbox.surface.3", 1, 1.0f, {784, -24, 1044, 136}, {0, 0, 260, 160}},
};
EXPECT_CALL(*renderer, draw(_, Rect{0, 0,
......@@ -241,5 +241,103 @@ TEST(LayerComposer, PopupShouldNotCauseWindowLayerOffset) {
composer.submit_layers(renderables);
}
TEST(LayerComposer, ResizingShouldUseOldRender) {
auto renderer = std::make_shared<MockRenderer>();
platform::Configuration config;
// The default policy will create a dumb window instance when requested
// from the manager.
auto platform = platform::create(std::string(), nullptr, config);
auto app_db = std::make_shared<application::Database>();
auto wm = std::make_shared<wm::MultiWindowManager>(platform, nullptr, app_db);
auto single_window = wm::WindowState{
wm::Display::Id{1},
true,
graphics::Rect{1120, 270, 2144, 1038},
"org.anbox.foo",
wm::Task::Id{3},
wm::Stack::Id::Freeform,
};
auto window = platform->create_window(single_window.task(), single_window.frame(), single_window.package_name());
window->attach();
wm->insert_task(single_window.task(), window);
LayerComposer composer(renderer, std::make_shared<MultiWindowComposerStrategy>(wm));
RenderableList renderables_first = {
{"org.anbox.surface.3", 0, 1.0f, {1120,270,2144,1038}, {0, 0, 1024, 768}},
};
composer.submit_layers(renderables_first);
window->update_frame(graphics::Rect{0, 0, 1024, 768});
window->setResizing(true);
composer.submit_layers(renderables_first);
RenderableList expected_renderables{
{"org.anbox.surface.3", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
};
EXPECT_CALL(*renderer, draw(_, Rect{0, 0,
single_window.frame().width(),
single_window.frame().height()},
expected_renderables))
.Times(1)
.WillOnce(Return(true));
composer.submit_layers(renderables_first);
}
TEST(LayerComposer, ResizeOverShouldUseNewRender) {
auto renderer = std::make_shared<MockRenderer>();
platform::Configuration config;
// The default policy will create a dumb window instance when requested
// from the manager.
auto platform = platform::create(std::string(), nullptr, config);
auto app_db = std::make_shared<application::Database>();
auto wm = std::make_shared<wm::MultiWindowManager>(platform, nullptr, app_db);
auto single_window = wm::WindowState{
wm::Display::Id{1},
true,
graphics::Rect{1120, 270, 2144, 1038},
"org.anbox.foo",
wm::Task::Id{3},
wm::Stack::Id::Freeform,
};
auto window = platform->create_window(single_window.task(), single_window.frame(), single_window.package_name());
window->attach();
wm->insert_task(single_window.task(), window);
LayerComposer composer(renderer, std::make_shared<MultiWindowComposerStrategy>(wm));
RenderableList renderables_first = {
{"org.anbox.surface.3", 0, 1.0f, {1120,270,2144,1038}, {0, 0, 1024, 768}},
};
RenderableList renderables_second = {
{"org.anbox.surface.3", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
};
composer.submit_layers(renderables_first);
window->update_frame(graphics::Rect{0, 0, 1024, 768});
window->setResizing(true);
composer.submit_layers(renderables_first);
RenderableList expected_renderables{
{"org.anbox.surface.3", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
};
EXPECT_CALL(*renderer, draw(_, Rect{0, 0,
single_window.frame().width(),
single_window.frame().height()},
expected_renderables))
.Times(1)
.WillOnce(Return(true));
composer.submit_layers(renderables_second);
EXPECT_TRUE(window->checkResizeable() == false);
}
} // namespace graphics
} // namespace anbox
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册