Restructure window creation and mangement

This commit is contained in:
Simon Fels 2016-11-20 17:08:05 +01:00
commit d4b4a795c3
28 changed files with 398 additions and 506 deletions

View file

@ -103,17 +103,14 @@ set(SOURCES
anbox/graphics/opengles_message_processor.cpp anbox/graphics/opengles_message_processor.cpp
anbox/graphics/gl_renderer_server.cpp anbox/graphics/gl_renderer_server.cpp
anbox/graphics/window_creator.cpp
anbox/graphics/density.h anbox/graphics/density.h
anbox/graphics/rect.cpp anbox/graphics/rect.cpp
anbox/graphics/emugl/ColorBuffer.cpp anbox/graphics/emugl/ColorBuffer.cpp
anbox/graphics/emugl/DisplayManager.cpp anbox/graphics/emugl/DisplayManager.cpp
anbox/graphics/emugl/RendererConfig.cpp anbox/graphics/emugl/RendererConfig.cpp
anbox/graphics/emugl/Renderable.cpp
anbox/graphics/emugl/Renderer.cpp anbox/graphics/emugl/Renderer.cpp
anbox/graphics/emugl/LayerManager.cpp
anbox/graphics/emugl/NativeSubWindow_delegate.cpp
anbox/graphics/emugl/NativeSubWindow.h
anbox/graphics/emugl/ReadBuffer.cpp anbox/graphics/emugl/ReadBuffer.cpp
anbox/graphics/emugl/RenderApi.cpp anbox/graphics/emugl/RenderApi.cpp
anbox/graphics/emugl/RenderContext.cpp anbox/graphics/emugl/RenderContext.cpp
@ -132,6 +129,7 @@ set(SOURCES
anbox/wm/display.cpp anbox/wm/display.cpp
anbox/wm/task.cpp anbox/wm/task.cpp
anbox/wm/stack.cpp
anbox/wm/manager.cpp anbox/wm/manager.cpp
anbox/wm/window_state.cpp anbox/wm/window_state.cpp
anbox/wm/window.cpp anbox/wm/window.cpp
@ -158,9 +156,9 @@ set(SOURCES
anbox/bridge/platform_api_skeleton.cpp anbox/bridge/platform_api_skeleton.cpp
anbox/bridge/android_api_stub.cpp anbox/bridge/android_api_stub.cpp
anbox/ubuntu/window_creator.cpp
anbox/ubuntu/window.cpp anbox/ubuntu/window.cpp
anbox/ubuntu/keycode_converter.cpp anbox/ubuntu/keycode_converter.cpp
anbox/ubuntu/platform_policy.cpp
anbox/dbus/interface.h anbox/dbus/interface.h
anbox/dbus/skeleton/service.cpp anbox/dbus/skeleton/service.cpp

View file

@ -51,12 +51,17 @@ void PlatformApiSkeleton::update_window_state(anbox::protobuf::bridge::WindowSta
(void) response; (void) response;
auto convert_window_state = [](const ::anbox::protobuf::bridge::WindowStateUpdate_WindowState &window) { auto convert_window_state = [](const ::anbox::protobuf::bridge::WindowStateUpdate_WindowState &window) {
DEBUG("Window: display=%d has_surface=%d frame={%d,%d,%d,%d} package=%s task=%d stack=-1",
window.display_id(), window.has_surface(),
window.frame_left(), window.frame_top(), window.frame_right(), window.frame_bottom(),
window.package_name(), window.task_id());
return wm::WindowState( return wm::WindowState(
wm::Display::Id(window.display_id()), wm::Display::Id(window.display_id()),
window.has_surface(), window.has_surface(),
graphics::Rect(window.frame_left(), window.frame_top(), window.frame_right(), window.frame_bottom()), graphics::Rect(window.frame_left(), window.frame_top(), window.frame_right(), window.frame_bottom()),
window.package_name(), window.package_name(),
wm::Task::Id(window.task_id())); wm::Task::Id(window.task_id()),
wm::Stack::Id(wm::Stack::Invalid));
}; };
wm::WindowState::List updated; wm::WindowState::List updated;
@ -68,7 +73,7 @@ void PlatformApiSkeleton::update_window_state(anbox::protobuf::bridge::WindowSta
wm::WindowState::List removed; wm::WindowState::List removed;
for (int n = 0; n < request->removed_windows_size(); n++) { for (int n = 0; n < request->removed_windows_size(); n++) {
const auto window = request->removed_windows(n); const auto window = request->removed_windows(n);
updated.push_back(convert_window_state(window)); removed.push_back(convert_window_state(window));
} }
window_manager_->apply_window_state_update(updated, removed); window_manager_->apply_window_state_update(updated, removed);

View file

@ -33,11 +33,10 @@
#include "anbox/bridge/platform_message_processor.h" #include "anbox/bridge/platform_message_processor.h"
#include "anbox/bridge/android_api_stub.h" #include "anbox/bridge/android_api_stub.h"
#include "anbox/bridge/platform_api_skeleton.h" #include "anbox/bridge/platform_api_skeleton.h"
#include "anbox/ubuntu/window_creator.h"
#include "anbox/dbus/skeleton/service.h" #include "anbox/dbus/skeleton/service.h"
#include "anbox/container/client.h" #include "anbox/container/client.h"
#include "anbox/wm/manager.h" #include "anbox/wm/manager.h"
#include "anbox/wm/default_platform_policy.h" #include "anbox/ubuntu/platform_policy.h"
#include <sys/prctl.h> #include <sys/prctl.h>
@ -90,11 +89,13 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory)
auto input_manager = std::make_shared<input::Manager>(rt); auto input_manager = std::make_shared<input::Manager>(rt);
auto policy = std::make_shared<wm::DefaultPlatformPolicy>(); auto policy = std::make_shared<ubuntu::PlatformPolicy>(input_manager);
// FIXME this needs to be removed and solved differently behind the scenes
registerDisplayManager(policy);
auto window_manager = std::make_shared<wm::Manager>(policy); auto window_manager = std::make_shared<wm::Manager>(policy);
auto window_creator = std::make_shared<ubuntu::WindowCreator>(input_manager); auto renderer = std::make_shared<graphics::GLRendererServer>();
auto renderer = std::make_shared<graphics::GLRendererServer>(window_creator);
renderer->start(); renderer->start();
// Socket which will be used by the qemud service inside the Android // Socket which will be used by the qemud service inside the Android

View file

@ -23,7 +23,6 @@
#include <memory> #include <memory>
class TextureDraw; class TextureDraw;
class TextureResize; class TextureResize;

View file

@ -1,130 +0,0 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "LayerManager.h"
#include <algorithm>
#include <boost/algorithm/string.hpp>
namespace {
std::string get_package_name(const std::string &name) {
return name;
}
bool is_layer_blacklisted(const std::string &name) {
static std::vector<std::string> blacklist = {
// The boot animation should be disabled already but we blacklist it
// here too to ensure it is never visible.
"BootAnimation",
"StatusBar",
"Sprite",
"KeyguardScrim",
"com.android.launcher/com.android.launcher2.Launcher",
"com.android.settings/com.android.settings.FallbackHome",
"com.android.systemui.ImageWallpaper",
"InputMethod",
"com.android.quicksearchbox/com.android.quicksearchbox.SearchActivity",
};
return std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end();
}
struct ActivityInfo {
ActivityInfo(const std::string &name) :
name(name) {
std::vector<std::string> parts;
boost::split(parts, name, boost::is_any_of("/"));
if (parts.size() > 1)
package = parts[0];
}
std::string package;
std::string name;
};
bool from_same_package(const std::string &a, const std::string &b) {
return ActivityInfo(a).package == ActivityInfo(b).package;
}
}
std::shared_ptr<LayerManager> LayerManager::get() {
static auto self = std::shared_ptr<LayerManager>{new LayerManager};
return self;
}
LayerManager::LayerManager() {
}
LayerManager::~LayerManager() {
}
void LayerManager::post_layer(const LayerInfo &layer) {
if (is_layer_blacklisted(layer.name))
return;
RendererWindow *window = nullptr;
for (auto &l : layers_) {
if (l.first == layer.name || from_same_package(l.first, layer.name)) {
window = l.second.window;
l.second.updated = true;
}
}
auto width = layer.display_frame.right - layer.display_frame.left;
auto height = layer.display_frame.bottom - layer.display_frame.top;
if (!window) {
printf("New layer '%s' display_frame={%d,%d,%d,%d} source_crop={%d,%d,%d,%d}\n",
layer.name.c_str(),
layer.display_frame.left,
layer.display_frame.top,
layer.display_frame.right,
layer.display_frame.bottom,
layer.source_crop.left,
layer.source_crop.top,
layer.source_crop.right,
layer.source_crop.bottom);
window = Renderer::get()->createWindow(layer.display_frame.left,
layer.display_frame.top,
width, height);
if (!window) {
printf("Failed to create window for layer '%s'\n", layer.name.c_str());
return;
}
layers_.insert({ layer.name, Layer{window, true}});
}
Renderer::get()->updateWindow(window,
layer.display_frame.left,
layer.display_frame.top,
width, height);
Renderer::get()->post(window, layer.buffer_handle);
}
void LayerManager::finish_cycle() {
for (auto iter = layers_.begin(); iter != layers_.end(); ++iter) {
if (!iter->second.updated) {
Renderer::get()->destroyWindow(iter->second.window);
layers_.erase(iter);
}
}
for (auto &layer : layers_)
layer.second.updated = false;
}

View file

@ -1,63 +0,0 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef LAYER_MANAGER_H_
#define LAYER_MANAGER_H_
#include <memory>
#include <map>
#include <vector>
#include <string>
#include "Renderer.h"
struct LayerRect {
int left;
int top;
int right;
int bottom;
};
struct LayerInfo {
std::string name;
LayerRect source_crop;
LayerRect display_frame;
HandleType buffer_handle;
};
class LayerManager {
public:
static std::shared_ptr<LayerManager> get();
~LayerManager();
void post_layer(const LayerInfo &layer);
void finish_cycle();
private:
LayerManager();
struct Layer {
RendererWindow *window;
bool updated;
};
std::map<std::string,Layer> layers_;
};
#endif

View file

@ -1,68 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef NATIVE_SUB_WINDOW_H
#define NATIVE_SUB_WINDOW_H
#include "OpenglRender/render_api_platform_types.h"
#include <EGL/egl.h>
#include <memory>
#ifdef __cplusplus
extern "C" {
#endif
class SubWindowHandler {
public:
virtual ~SubWindowHandler() { }
virtual EGLNativeWindowType create_window(int x, int y, int width, int height) = 0;
virtual void update_window(EGLNativeWindowType win, int x, int y, int width, int height) = 0;
virtual void destroy_window(EGLNativeWindowType win) = 0;
};
void registerSubWindowHandler(const std::shared_ptr<SubWindowHandler> &handler);
// Create a new sub-window that will be used to display the content of the
// emulated GPU on top of the regular UI window.
// |p_window| is the platform-specific handle to the main UI window.
// |x|, |y| is the position sub-window relative to the top-left corner of the
// main window.
// |width| and |height| are the dimensions of the sub-window, as well as of
// the emulated framebuffer.
// |repaint_callback| may be invoked every time the window has to be repainted
// (such as receiving a WM_PAINT event on Windows). If the provided argument is
// NULL, nothing will be invoked.
// |repaint_callback_param| an additional parameter that will be passed to the
// repaint callback when/if it's invoked.
// On success, return a new platform-specific window handle, cast as an
// EGLNativeWindowType. Or 0/NULL in case of failure.
EGLNativeWindowType createSubWindow(FBNativeWindowType p_window,
int x,
int y,
int width,
int height);
void updateSubWindow(EGLNativeWindowType win, int x, int y, int width, int height);
// Destroy a sub-window previously created through createSubWindow() above.
void destroySubWindow(EGLNativeWindowType win);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,59 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "NativeSubWindow.h"
#include <stdexcept>
#include <string>
#include <map>
namespace {
static std::shared_ptr<SubWindowHandler> current_handler = nullptr;
}
void registerSubWindowHandler(const std::shared_ptr<SubWindowHandler> &handler) {
if (current_handler)
throw std::runtime_error("A sub window handle is already registered");
current_handler = handler;
}
EGLNativeWindowType createSubWindow(FBNativeWindowType p_window,
int x,
int y,
int width,
int height) {
(void) p_window;
if (!current_handler)
return (EGLNativeWindowType) 0;
return current_handler->create_window(x, y, width, height);
}
void updateSubWindow(EGLNativeWindowType win, int x, int y, int width, int height) {
if (!current_handler)
return;
return current_handler->update_window(win, x, y, width, height);
}
void destroySubWindow(EGLNativeWindowType win) {
if (!current_handler)
return;
return current_handler->destroy_window(win);
}

View file

@ -20,7 +20,6 @@
#include "Renderer.h" #include "Renderer.h"
#include "RenderThreadInfo.h" #include "RenderThreadInfo.h"
#include "ChecksumCalculatorThreadInfo.h" #include "ChecksumCalculatorThreadInfo.h"
#include "LayerManager.h"
#include "DisplayManager.h" #include "DisplayManager.h"
#include "OpenGLESDispatch/EGLDispatch.h" #include "OpenGLESDispatch/EGLDispatch.h"
@ -432,14 +431,9 @@ void rcPostLayer(const char *name, uint32_t color_buffer,
int32_t displayFrameLeft, int32_t displayFrameTop, int32_t displayFrameLeft, int32_t displayFrameTop,
int32_t displayFrameRight, int32_t displayFrameBottom) { int32_t displayFrameRight, int32_t displayFrameBottom) {
LayerRect source_crop{sourceCropLeft, sourceCropTop, sourceCropRight, sourceCropBottom};
LayerRect display_frame{displayFrameLeft, displayFrameTop, displayFrameRight, displayFrameBottom};
LayerManager::get()->post_layer({name, source_crop, display_frame, color_buffer});
} }
void rcPostAllLayersDone() void rcPostAllLayersDone() {
{
LayerManager::get()->finish_cycle();
} }
void initRenderControlContext(renderControl_decoder_context_t *dec) void initRenderControlContext(renderControl_decoder_context_t *dec)

View file

@ -0,0 +1,38 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Renderable.h"
Renderable::Renderable(const std::uint32_t &buffer,
const anbox::graphics::Rect &screen_position) :
buffer_(buffer),
screen_position_(screen_position)
{
}
Renderable::~Renderable()
{
}
std::uint32_t Renderable::buffer() const
{
return buffer_;
}
anbox::graphics::Rect Renderable::screen_position() const
{
return screen_position_;
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ANBOX_GRAPHICS_EMUGL_RENDERABLE_H_
#define ANBOX_GRAPHICS_EMUGL_RENDERABLE_H_
#include "anbox/graphics/rect.h"
#include <vector>
#include <cstdint>
class Renderable
{
public:
Renderable(const std::uint32_t &buffer,
const anbox::graphics::Rect &screen_position);
~Renderable();
std::uint32_t buffer() const;
anbox::graphics::Rect screen_position() const;
private:
std::uint32_t buffer_;
anbox::graphics::Rect screen_position_;
};
typedef std::vector<Renderable> RenderableList;
#endif

View file

@ -17,7 +17,6 @@
#include "Renderer.h" #include "Renderer.h"
#include "DispatchTables.h" #include "DispatchTables.h"
#include "NativeSubWindow.h"
#include "RenderThreadInfo.h" #include "RenderThreadInfo.h"
#include "TimeUtils.h" #include "TimeUtils.h"
#include "gles2_dec.h" #include "gles2_dec.h"
@ -456,40 +455,32 @@ Renderer::~Renderer() {
struct RendererWindow { struct RendererWindow {
EGLNativeWindowType native_window = 0; EGLNativeWindowType native_window = 0;
EGLSurface surface = EGL_NO_SURFACE; EGLSurface surface = EGL_NO_SURFACE;
bool needViewportUpdate = false;
int width;
int height;
}; };
RendererWindow* Renderer::createWindow(int x, int y, int width, int height) { RendererWindow* Renderer::createNativeWindow(EGLNativeWindowType native_window)
{
m_lock.lock(); m_lock.lock();
auto native_window = createSubWindow(0, x, y, width, height);
if (!native_window) {
m_lock.unlock();
return nullptr;
}
auto window = new RendererWindow; auto window = new RendererWindow;
window->native_window = native_window; window->native_window = native_window;
window->width = width;
window->height = height;
window->surface = s_egl.eglCreateWindowSurface( window->surface = s_egl.eglCreateWindowSurface(
m_eglDisplay, m_eglConfig, window->native_window, nullptr); m_eglDisplay, m_eglConfig, window->native_window, nullptr);
if (window->surface == EGL_NO_SURFACE) { if (window->surface == EGL_NO_SURFACE)
destroyWindow(window); {
delete window;
m_lock.unlock(); m_lock.unlock();
return nullptr; return nullptr;
} }
if (!bindWindow_locked(window)) { if (!bindWindow_locked(window))
destroyWindow(window); {
s_egl.eglDestroySurface(m_eglDisplay, window->surface);
delete window;
m_lock.unlock(); m_lock.unlock();
return nullptr; return nullptr;
} }
s_gles2.glViewport(0, 0, width, height); // s_gles2.glViewport(0, 0, width, height);
s_gles2.glClear(GL_COLOR_BUFFER_BIT | s_gles2.glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT); GL_STENCIL_BUFFER_BIT);
@ -497,35 +488,27 @@ RendererWindow* Renderer::createWindow(int x, int y, int width, int height) {
unbind_locked(); unbind_locked();
m_nativeWindows.insert({native_window, window});
m_lock.unlock(); m_lock.unlock();
return window; return window;
} }
void Renderer::updateWindow(RendererWindow *window, int x, int y, int width, int height) { void Renderer::destroyNativeWindow(EGLNativeWindowType native_window) {
if (!window) auto w = m_nativeWindows.find(native_window);
return; if (w == m_nativeWindows.end())
updateSubWindow(window->native_window, x, y, width, height);
window->width = width;
window->height = height;
window->needViewportUpdate = true;
}
void Renderer::destroyWindow(RendererWindow *window) {
if (!window)
return; return;
m_lock.lock(); m_lock.lock();
s_egl.eglMakeCurrent(m_eglDisplay, nullptr, nullptr, nullptr); s_egl.eglMakeCurrent(m_eglDisplay, nullptr, nullptr, nullptr);
if (window->surface != EGL_NO_SURFACE) if (w->second->surface != EGL_NO_SURFACE)
s_egl.eglDestroySurface(m_eglDisplay, window->surface); s_egl.eglDestroySurface(m_eglDisplay, w->second->surface);
destroySubWindow(window->native_window); delete w->second;
m_nativeWindows.erase(w);
delete window;
m_lock.unlock(); m_lock.unlock();
} }
@ -990,10 +973,12 @@ bool Renderer::post(RendererWindow *window, HandleType p_colorbuffer, bool needL
if (!bindWindow_locked(window)) if (!bindWindow_locked(window))
goto EXIT; goto EXIT;
#if 0
if (window->needViewportUpdate) { if (window->needViewportUpdate) {
s_gles2.glViewport(0, 0, window->width, window->height); s_gles2.glViewport(0, 0, window->width, window->height);
window->needViewportUpdate = false; window->needViewportUpdate = false;
} }
#endif
s_gles2.glClearColor(0.0, 0.0, 1.0, 0.0); s_gles2.glClearColor(0.0, 0.0, 1.0, 0.0);
s_gles2.glClear(GL_COLOR_BUFFER_BIT); s_gles2.glClear(GL_COLOR_BUFFER_BIT);
@ -1029,3 +1014,39 @@ EXIT:
} }
return ret; return ret;
} }
bool Renderer::draw(EGLNativeWindowType native_window, const RenderableList &renderables)
{
auto w = m_nativeWindows.find(native_window);
if (w == m_nativeWindows.end())
return false;
if (!bindWindow_locked(w->second))
{
m_lock.unlock();
return false;
}
s_gles2.glClearColor(0.0, 0.0, 1.0, 0.0);
s_gles2.glClear(GL_COLOR_BUFFER_BIT);
for (const auto &renderable : renderables)
{
const auto &color_buffer = m_colorbuffers.find(renderable.buffer());
if (color_buffer == m_colorbuffers.end())
continue;
color_buffer->second.cb->post(0.0f,
renderable.screen_position().left(), renderable.screen_position().top());
}
s_egl.eglSwapBuffers(m_eglDisplay, w->second->surface);
unbind_locked();
m_lock.lock();
m_lock.unlock();
return false;
}

View file

@ -25,6 +25,8 @@
#include "OpenglRender/render_api.h" #include "OpenglRender/render_api.h"
#include "Renderable.h"
#include <EGL/egl.h> #include <EGL/egl.h>
#include <map> #include <map>
@ -78,10 +80,6 @@ public:
// Returns true on success, false otherwise. // Returns true on success, false otherwise.
static bool initialize(EGLNativeDisplayType nativeDisplay); static bool initialize(EGLNativeDisplayType nativeDisplay);
RendererWindow* createWindow(int x, int y, int width, int height);
void updateWindow(RendererWindow *window, int x, int y, int width, int height);
void destroyWindow(RendererWindow *window);
// Finalize the instance. // Finalize the instance.
void finalize(); void finalize();
@ -111,6 +109,10 @@ public:
*version = m_glVersion; *version = m_glVersion;
} }
RendererWindow* createNativeWindow(EGLNativeWindowType native_window);
void destroyNativeWindow(RendererWindow *window);
void destroyNativeWindow(EGLNativeWindowType native_window);
// Create a new RenderContext instance for this display instance. // Create a new RenderContext instance for this display instance.
// |p_config| is the index of one of the configs returned by getConfigs(). // |p_config| is the index of one of the configs returned by getConfigs().
// |p_share| is either EGL_NO_CONTEXT or the handle of a shared context. // |p_share| is either EGL_NO_CONTEXT or the handle of a shared context.
@ -234,6 +236,8 @@ public:
// false only when called internally. // false only when called internally.
bool post(RendererWindow *window, HandleType p_colorbuffer, bool needLock = true); bool post(RendererWindow *window, HandleType p_colorbuffer, bool needLock = true);
bool draw(EGLNativeWindowType native_window, const RenderableList &renderables);
// Return the host EGLDisplay used by this instance. // Return the host EGLDisplay used by this instance.
EGLDisplay getDisplay() const { return m_eglDisplay; } EGLDisplay getDisplay() const { return m_eglDisplay; }
@ -286,5 +290,7 @@ private:
const char* m_glVendor; const char* m_glVendor;
const char* m_glRenderer; const char* m_glRenderer;
const char* m_glVersion; const char* m_glVersion;
std::map<EGLNativeWindowType,RendererWindow*> m_nativeWindows;
}; };
#endif #endif

View file

@ -17,7 +17,6 @@
#include "anbox/logger.h" #include "anbox/logger.h"
#include "anbox/graphics/gl_renderer_server.h" #include "anbox/graphics/gl_renderer_server.h"
#include "anbox/graphics/window_creator.h"
#include "OpenglRender/render_api.h" #include "OpenglRender/render_api.h"
@ -27,8 +26,8 @@
namespace anbox { namespace anbox {
namespace graphics { namespace graphics {
GLRendererServer::GLRendererServer(const std::shared_ptr<WindowCreator> &window_creator) : GLRendererServer::GLRendererServer()
window_creator_(window_creator) { {
if (utils::is_env_set("USE_HOST_GLES")) { if (utils::is_env_set("USE_HOST_GLES")) {
// Force the host EGL/GLES libraries as translator implementation // Force the host EGL/GLES libraries as translator implementation
@ -44,13 +43,9 @@ GLRendererServer::GLRendererServer(const std::shared_ptr<WindowCreator> &window_
if (!initLibrary()) if (!initLibrary())
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize OpenGL renderer")); BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize OpenGL renderer"));
registerSubWindowHandler(window_creator_);
registerDisplayManager(window_creator_);
} }
GLRendererServer::~GLRendererServer() { GLRendererServer::~GLRendererServer() {
// destroyOpenGLSubwindow();
stopOpenGLRenderer(); stopOpenGLRenderer();
} }
@ -70,15 +65,11 @@ void GLRendererServer::start() {
log_funcs.coarse = logger_write; log_funcs.coarse = logger_write;
log_funcs.fine = logger_write; log_funcs.fine = logger_write;
auto display_info = window_creator_->display_info();
const auto width = display_info.horizontal_resolution;
const auto height = display_info.vertical_resolution;
char server_addr[256] = { 0 }; char server_addr[256] = { 0 };
// The width & height we supply here are the dimensions the internal framebuffer // The width & height we supply here are the dimensions the internal framebuffer
// will use. Making this static prevents us for now to resize the window we create // will use. Making this static prevents us for now to resize the window we create
// later for the actual display. // later for the actual display.
if (!initOpenGLRenderer(window_creator_->native_display(), server_addr, sizeof(server_addr), log_funcs, logger_write)) if (!initOpenGLRenderer(0, server_addr, sizeof(server_addr), log_funcs, logger_write))
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to setup OpenGL renderer")); BOOST_THROW_EXCEPTION(std::runtime_error("Failed to setup OpenGL renderer"));
socket_path_ = server_addr; socket_path_ = server_addr;

View file

@ -29,7 +29,7 @@ namespace graphics {
class WindowCreator; class WindowCreator;
class GLRendererServer { class GLRendererServer {
public: public:
GLRendererServer(const std::shared_ptr<WindowCreator> &window_creator); GLRendererServer();
~GLRendererServer(); ~GLRendererServer();
void start(); void start();
@ -38,7 +38,6 @@ public:
private: private:
std::string socket_path_; std::string socket_path_;
std::shared_ptr<WindowCreator> window_creator_;
}; };
} // namespace graphics } // namespace graphics

View file

@ -15,7 +15,7 @@
* *
*/ */
#include "anbox/ubuntu/window_creator.h" #include "anbox/ubuntu/platform_policy.h"
#include "anbox/ubuntu/window.h" #include "anbox/ubuntu/window.h"
#include "anbox/ubuntu/keycode_converter.h" #include "anbox/ubuntu/keycode_converter.h"
#include "anbox/input/manager.h" #include "anbox/input/manager.h"
@ -29,16 +29,14 @@
namespace anbox { namespace anbox {
namespace ubuntu { namespace ubuntu {
WindowCreator::WindowCreator(const std::shared_ptr<input::Manager> &input_manager) : PlatformPolicy::PlatformPolicy(const std::shared_ptr<input::Manager> &input_manager) :
graphics::WindowCreator(input_manager),
input_manager_(input_manager), input_manager_(input_manager),
event_thread_running_(false), event_thread_running_(false) {
display_info_({1920, 1080}) {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0)
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize SDL")); BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize SDL"));
event_thread_ = std::thread(&WindowCreator::process_events, this); event_thread_ = std::thread(&PlatformPolicy::process_events, this);
SDL_DisplayMode display_mode; SDL_DisplayMode display_mode;
// FIXME statically just check the first (primary) display for its mode; // FIXME statically just check the first (primary) display for its mode;
@ -71,12 +69,12 @@ WindowCreator::WindowCreator(const std::shared_ptr<input::Manager> &input_manage
keyboard_->set_key_bit(KEY_OK); keyboard_->set_key_bit(KEY_OK);
} }
WindowCreator::~WindowCreator() { PlatformPolicy::~PlatformPolicy() {
event_thread_running_ = false; event_thread_running_ = false;
event_thread_.join(); event_thread_.join();
} }
void WindowCreator::process_events() { void PlatformPolicy::process_events() {
event_thread_running_ = true; event_thread_running_ = true;
while(event_thread_running_) { while(event_thread_running_) {
@ -90,9 +88,11 @@ void WindowCreator::process_events() {
break; break;
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
for (auto &iter : windows_) { for (auto &iter : windows_) {
if (iter.second->id() == event.window.windowID) { if (auto w = iter.second.lock()) {
iter.second->process_event(event); if (w->window_id() == event.window.windowID) {
break; w->process_event(event);
break;
}
} }
} }
break; break;
@ -109,7 +109,7 @@ void WindowCreator::process_events() {
} }
} }
void WindowCreator::process_input_event(const SDL_Event &event) { void PlatformPolicy::process_input_event(const SDL_Event &event) {
std::vector<input::Event> mouse_events; std::vector<input::Event> mouse_events;
std::vector<input::Event> keyboard_events; std::vector<input::Event> keyboard_events;
@ -176,44 +176,29 @@ void WindowCreator::process_input_event(const SDL_Event &event) {
keyboard_->send_events(keyboard_events); keyboard_->send_events(keyboard_events);
} }
EGLNativeWindowType WindowCreator::create_window(int x, int y, int width, int height) Window::Id PlatformPolicy::next_window_id() {
try { static Window::Id next_id = 0;
auto window = std::make_shared<Window>(x, y, width, height); return next_id++;
if (not window)
BOOST_THROW_EXCEPTION(std::bad_alloc());
windows_.insert({window->native_window(), window});
return window->native_window();
}
catch (std::exception &err) {
DEBUG("Failed to create window: %s", err.what());
return 0;
} }
void WindowCreator::update_window(EGLNativeWindowType win, int x, int y, int width, int height) { std::shared_ptr<wm::Window> PlatformPolicy::create_window(const wm::WindowState &state) {
auto iter = windows_.find(win); auto id = next_window_id();
if (iter == windows_.end()) auto w = std::make_shared<Window>(id, shared_from_this(), state);
windows_.insert({id, w});
return w;
}
void PlatformPolicy::window_deleted(const Window::Id &id) {
auto w = windows_.find(id);
if (w == windows_.end()) {
WARNING("Got window removed event for unknown window (id %d)", id);
return; return;
}
iter->second->resize(width, height); windows_.erase(w);
iter->second->update_position(x, y);
} }
void WindowCreator::destroy_window(EGLNativeWindowType win) { DisplayManager::DisplayInfo PlatformPolicy::display_info() const {
auto iter = windows_.find(win);
if (iter == windows_.end())
return;
windows_.erase(iter);
}
WindowCreator::DisplayInfo WindowCreator::display_info() const {
return display_info_; return display_info_;
} }
} // namespace wm
EGLNativeDisplayType WindowCreator::native_display() const {
return 0;
}
} // namespace bridge
} // namespace anbox } // namespace anbox

View file

@ -15,15 +15,17 @@
* *
*/ */
#ifndef ANBOX_UBUNTU_WINDOW_CREATOR_H_ #ifndef ANBOX_UBUNTU_PLATFORM_POLICY_H_
#define ANBOX_UBUNTU_WINDOW_CREATOR_H_ #define ANBOX_UBUNTU_PLATFORM_POLICY_H_
#include "anbox/graphics/window_creator.h" #include "anbox/wm/platform_policy.h"
#include "anbox/ubuntu/window.h"
#include "anbox/graphics/emugl/DisplayManager.h"
#include <map>
#include <thread> #include <thread>
#include <map>
#include <EGL/egl.h>
#include <SDL.h> #include <SDL.h>
namespace anbox { namespace anbox {
@ -32,34 +34,38 @@ class Device;
class Manager; class Manager;
} // namespace input } // namespace input
namespace ubuntu { namespace ubuntu {
class MirDisplayConnection; class PlatformPolicy : public std::enable_shared_from_this<PlatformPolicy>,
class Window; public wm::PlatformPolicy,
class WindowCreator : public graphics::WindowCreator { public Window::Observer,
public DisplayManager {
public: public:
WindowCreator(const std::shared_ptr<input::Manager> &input_manager); PlatformPolicy(const std::shared_ptr<input::Manager> &input_manager);
~WindowCreator(); ~PlatformPolicy();
EGLNativeWindowType create_window(int x, int y, int width, int height) override; std::shared_ptr<wm::Window> create_window(const wm::WindowState &state) override;
void update_window(EGLNativeWindowType win, int x, int y, int width, int height) override;
void destroy_window(EGLNativeWindowType win) override; void window_deleted(const Window::Id &id) override;
DisplayInfo display_info() const override; DisplayInfo display_info() const override;
EGLNativeDisplayType native_display() const override;
private: private:
void process_events(); void process_events();
void process_input_event(const SDL_Event &event); void process_input_event(const SDL_Event &event);
static Window::Id next_window_id();
std::shared_ptr<input::Manager> input_manager_; std::shared_ptr<input::Manager> input_manager_;
std::map<EGLNativeWindowType,std::shared_ptr<Window>> windows_; // We don't own the windows anymore after the got created by us so we
// need to be careful once we try to use them again.
std::map<Window::Id, std::weak_ptr<Window>> windows_;
std::shared_ptr<Window> current_window_; std::shared_ptr<Window> current_window_;
std::thread event_thread_; std::thread event_thread_;
bool event_thread_running_; bool event_thread_running_;
graphics::WindowCreator::DisplayInfo display_info_;
std::shared_ptr<input::Device> pointer_; std::shared_ptr<input::Device> pointer_;
std::shared_ptr<input::Device> keyboard_; std::shared_ptr<input::Device> keyboard_;
DisplayManager::DisplayInfo display_info_;
}; };
} // namespace ubuntu } // namespace wm
} // namespace anbox } // namespace anbox
#endif #endif

View file

@ -16,15 +16,69 @@
*/ */
#include "anbox/ubuntu/window.h" #include "anbox/ubuntu/window.h"
#include "anbox/wm/window_state.h"
#include "anbox/logger.h" #include "anbox/logger.h"
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <SDL_syswm.h> #include <SDL_syswm.h>
namespace {
constexpr const char* default_window_name{"anbox"};
}
namespace anbox { namespace anbox {
namespace ubuntu { namespace ubuntu {
Window::Id Window::Invalid{-1};
Window::Observer::~Observer() {
}
Window::Window(const Id &id,
const std::shared_ptr<Observer> &observer,
const wm::WindowState &state) :
wm::Window(state),
id_(id),
observer_(observer),
native_display_(0),
native_window_(0) {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
window_ = SDL_CreateWindow(default_window_name,
state.frame().left(),
state.frame().top(),
state.frame().width(),
state.frame().height(),
SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS);
if (!window_) {
const auto message = utils::string_format("Failed to create window: %s", SDL_GetError());
BOOST_THROW_EXCEPTION(std::runtime_error(message));
}
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
SDL_GetWindowWMInfo(window_, &info);
switch (info.subsystem) {
case SDL_SYSWM_X11:
DEBUG("Running on X11");
native_display_ = static_cast<EGLNativeDisplayType>(info.info.x11.display);
native_window_ = static_cast<EGLNativeWindowType>(info.info.x11.window);
break;
default:
ERROR("Unknown subsystem (%d)", info.subsystem);
BOOST_THROW_EXCEPTION(std::runtime_error("SDL subsystem not suported"));
}
int actual_width = 0, actual_height = 0;
int actual_x = 0, actual_y = 0;
SDL_GetWindowSize(window_, &actual_width, &actual_height);
SDL_GetWindowPosition(window_, &actual_x, &actual_y);
DEBUG("Window created {%d,%d,%d,%d}", actual_x, actual_y, actual_width, actual_height);
}
Window::Window(int x, int y, int width, int height) : Window::Window(int x, int y, int width, int height) :
wm::Window(wm::WindowState()),
native_display_(0), native_display_(0),
native_window_(0) { native_window_(0) {
@ -60,6 +114,9 @@ Window::Window(int x, int y, int width, int height) :
Window::~Window() { Window::~Window() {
if (window_) if (window_)
SDL_DestroyWindow(window_); SDL_DestroyWindow(window_);
if (observer_)
observer_->window_deleted(id_);
} }
void Window::resize(int width, int height) { void Window::resize(int width, int height) {
@ -89,11 +146,15 @@ void Window::process_event(const SDL_Event &event) {
} }
} }
EGLNativeWindowType Window::native_window() const { EGLNativeWindowType Window::native_handle() const {
return native_window_; return native_window_;
} }
std::uint32_t Window::id() const { Window::Id Window::id() const {
return id_;
}
std::uint32_t Window::window_id() const {
return SDL_GetWindowID(window_); return SDL_GetWindowID(window_);
} }
} // namespace bridge } // namespace bridge

View file

@ -18,6 +18,8 @@
#ifndef ANBOX_UBUNTU_WINDOW_H_ #ifndef ANBOX_UBUNTU_WINDOW_H_
#define ANBOX_UBUNTU_WINDOW_H_ #define ANBOX_UBUNTU_WINDOW_H_
#include "anbox/wm/window.h"
#include <EGL/egl.h> #include <EGL/egl.h>
#include <memory> #include <memory>
@ -27,8 +29,19 @@
namespace anbox { namespace anbox {
namespace ubuntu { namespace ubuntu {
class Window { class Window : public std::enable_shared_from_this<Window>,
public wm::Window {
public: public:
typedef std::int32_t Id;
static Id Invalid;
class Observer {
public:
virtual ~Observer();
virtual void window_deleted(const Id &id) = 0;
};
Window(const Id &id, const std::shared_ptr<Observer> &observer, const wm::WindowState &state);
Window(int x, int y, int width, int height); Window(int x, int y, int width, int height);
~Window(); ~Window();
@ -37,10 +50,13 @@ public:
void process_event(const SDL_Event &event); void process_event(const SDL_Event &event);
EGLNativeWindowType native_window() const; EGLNativeWindowType native_handle() const override;
std::uint32_t id() const; Id id() const;
std::uint32_t window_id() const;
private: private:
Id id_;
std::shared_ptr<Observer> observer_;
EGLNativeDisplayType native_display_; EGLNativeDisplayType native_display_;
EGLNativeWindowType native_window_; EGLNativeWindowType native_window_;
SDL_Window *window_; SDL_Window *window_;

View file

@ -17,11 +17,12 @@
#include "anbox/wm/default_platform_policy.h" #include "anbox/wm/default_platform_policy.h"
#include "anbox/wm/window.h" #include "anbox/wm/window.h"
#include "anbox/logger.h"
namespace { namespace {
class Window : public anbox::wm::Window { class NullWindow : public anbox::wm::Window {
public: public:
Window(const anbox::wm::WindowState &state) : NullWindow(const anbox::wm::WindowState &state) :
anbox::wm::Window(state) { anbox::wm::Window(state) {
} }
}; };
@ -32,8 +33,10 @@ namespace wm {
DefaultPlatformPolicy::DefaultPlatformPolicy() { DefaultPlatformPolicy::DefaultPlatformPolicy() {
} }
std::shared_ptr<Window> DefaultPlatformPolicy::create_window(const WindowState &state) { std::shared_ptr<Window> DefaultPlatformPolicy::create_window(const WindowState &state)
return std::make_shared<::Window>(state); {
DEBUG("");
return std::make_shared<::NullWindow>(state);
} }
} // namespace wm } // namespace wm
} // namespace anbox } // namespace anbox

View file

@ -16,6 +16,7 @@
*/ */
#include "anbox/wm/manager.h" #include "anbox/wm/manager.h"
#include "anbox/wm/platform_policy.h"
#include "anbox/logger.h" #include "anbox/logger.h"
namespace anbox { namespace anbox {
@ -28,11 +29,39 @@ Manager::~Manager() {
} }
void Manager::apply_window_state_update(const WindowState::List &updated, void Manager::apply_window_state_update(const WindowState::List &updated,
const WindowState::List &removed) { const WindowState::List &removed)
(void) updated; {
(void) removed;
DEBUG("updated %d removed %d", updated.size(), removed.size()); DEBUG("updated %d removed %d", updated.size(), removed.size());
// Base on the update we get from the Android WindowManagerService we will create
// different window instances with the properties supplied. Incoming layer updates
// from SurfaceFlinger will be mapped later into those windows and eventually
// composited there via GLES (e.g. for popups, ..)
for (const auto &window : updated) {
auto w = windows_.find(window.task());
if (w != windows_.end()) {
DEBUG("Found existing window for task %d", window.task());
w->second->update_state(window);
continue;
}
DEBUG("Found new window for task %d", window.task());
auto platform_window = platform_->create_window(window);
platform_window->attach();
windows_.insert({window.task(), platform_window});
}
for (const auto &window : removed) {
auto w = windows_.find(window.task());
if (w == windows_.end()) {
WARNING("Got remove request for window we don't know about (task id %d)", window.task());
continue;
}
DEBUG("Removing window for task %d", window.task());
auto platform_window = w->second;
platform_window->release();
windows_.erase(w);
}
} }
} // namespace wm } // namespace wm
} // namespace anbox } // namespace anbox

View file

@ -19,8 +19,10 @@
#define ANBOX_WM_MANAGER_H_ #define ANBOX_WM_MANAGER_H_
#include "anbox/wm/window_state.h" #include "anbox/wm/window_state.h"
#include "anbox/wm/window.h"
#include <memory> #include <memory>
#include <map>
namespace anbox { namespace anbox {
namespace wm { namespace wm {
@ -35,6 +37,7 @@ public:
private: private:
std::shared_ptr<PlatformPolicy> platform_; std::shared_ptr<PlatformPolicy> platform_;
std::map<Task::Id, std::shared_ptr<Window>> windows_;
}; };
} // namespace wm } // namespace wm
} // namespace anbox } // namespace anbox

View file

@ -15,16 +15,13 @@
* *
*/ */
#include "anbox/graphics/window_creator.h" #include "anbox/wm/stack.h"
namespace anbox { namespace anbox {
namespace graphics { namespace wm {
WindowCreator::WindowCreator(const std::shared_ptr<input::Manager> &input_manager) : Stack::Id Stack::Invalid = -1;
input_manager_(input_manager) { Stack::Id Stack::Default = 0;
} Stack::Id Stack::Fullscreen = 1;
Stack::Id Stack::Freeform = 2;
WindowCreator::~WindowCreator() { } // namespace wm
}
} // namespace graphics
} // namespace anbox } // namespace anbox

View file

@ -15,28 +15,26 @@
* *
*/ */
#ifndef ANBOX_GRAPHICS_WINDOW_CREATOR_H_ #ifndef ANBOX_WM_STACK_H_
#define ANBOX_GRAPHICS_WINDOW_CREATOR_H_ #define ANBOX_WM_STACK_H_
#include "anbox/graphics/emugl/NativeSubWindow.h" #include <cstdint>
#include "anbox/graphics/emugl/DisplayManager.h"
namespace anbox { namespace anbox {
namespace input { namespace wm {
class Manager; class Stack {
} // namespace input
namespace graphics {
class WindowCreator : public SubWindowHandler,
public DisplayManager {
public: public:
WindowCreator(const std::shared_ptr<input::Manager> &input_manager); typedef std::int32_t Id;
virtual ~WindowCreator();
virtual EGLNativeDisplayType native_display() const = 0; static Id Invalid;
static Id Default;
static Id Fullscreen;
static Id Freeform;
protected: Stack() = delete;
std::shared_ptr<input::Manager> input_manager_; Stack(const Stack&) = delete;
}; };
} // namespace graphics } // namespace wm
} // namespace anbox } // namespace anbox
#endif #endif

View file

@ -16,6 +16,7 @@
*/ */
#include "anbox/wm/window.h" #include "anbox/wm/window.h"
#include "anbox/graphics/emugl/Renderer.h"
namespace anbox { namespace anbox {
namespace wm { namespace wm {
@ -30,8 +31,16 @@ void Window::update_state(const WindowState &state) {
state_ = state; state_ = state;
} }
void Window::render_layer(const Layer &layer) { EGLNativeWindowType Window::native_handle() const {
(void) layer; return 0;
}
bool Window::attach() {
return Renderer::get()->createNativeWindow(native_handle());
}
void Window::release() {
Renderer::get()->destroyNativeWindow(native_handle());
} }
} // namespace wm } // namespace wm
} // namespace anbox } // namespace anbox

View file

@ -23,6 +23,8 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <EGL/egl.h>
namespace anbox { namespace anbox {
namespace wm { namespace wm {
// FIXME(morphis): move this somewhere else once we have the integration // FIXME(morphis): move this somewhere else once we have the integration
@ -35,19 +37,20 @@ private:
graphics::Rect frame_; graphics::Rect frame_;
}; };
class Window { class Window
{
public: public:
typedef std::vector<Window> List; typedef std::vector<Window> List;
Window(const WindowState &state); Window(const WindowState &state);
virtual ~Window(); virtual ~Window();
bool attach();
void release();
void update_state(const WindowState &state); void update_state(const WindowState &state);
// Render a layer into the window. The layer itself includes all virtual EGLNativeWindowType native_handle() const;
// necessary information for correct rendering.
void render_layer(const Layer &layer);
WindowState state() const; WindowState state() const;
private: private:

View file

@ -24,19 +24,22 @@ WindowState::WindowState() :
has_surface_(false), has_surface_(false),
frame_(graphics::Rect::Invalid), frame_(graphics::Rect::Invalid),
package_name_(""), package_name_(""),
task_(Task::Invalid) { task_(Task::Invalid),
stack_(Stack::Invalid) {
} }
WindowState::WindowState(const Display::Id &display, WindowState::WindowState(const Display::Id &display,
bool has_surface, bool has_surface,
const graphics::Rect &frame, const graphics::Rect &frame,
const std::string &package_name, const std::string &package_name,
const Task::Id &task) : const Task::Id &task,
const Stack::Id &stack) :
display_(display), display_(display),
has_surface_(has_surface), has_surface_(has_surface),
frame_(frame), frame_(frame),
package_name_(package_name), package_name_(package_name),
task_(task) { task_(task),
stack_(stack) {
} }
WindowState::~WindowState() { WindowState::~WindowState() {

View file

@ -21,6 +21,7 @@
#include "anbox/graphics/rect.h" #include "anbox/graphics/rect.h"
#include "anbox/wm/display.h" #include "anbox/wm/display.h"
#include "anbox/wm/task.h" #include "anbox/wm/task.h"
#include "anbox/wm/stack.h"
#include <vector> #include <vector>
#include <string> #include <string>
@ -36,7 +37,8 @@ public:
bool has_surface, bool has_surface,
const graphics::Rect &frame, const graphics::Rect &frame,
const std::string &package_name, const std::string &package_name,
const Task::Id &task); const Task::Id &task,
const Stack::Id &stack);
~WindowState(); ~WindowState();
Display::Id display() const { return display_; } Display::Id display() const { return display_; }
@ -44,6 +46,7 @@ public:
graphics::Rect frame() const { return frame_; } graphics::Rect frame() const { return frame_; }
std::string package_name() const { return package_name_; } std::string package_name() const { return package_name_; }
Task::Id task() const { return task_; } Task::Id task() const { return task_; }
Stack::Id stack() const { return stack_; }
private: private:
Display::Id display_; Display::Id display_;
@ -51,6 +54,7 @@ private:
graphics::Rect frame_; graphics::Rect frame_;
std::string package_name_; std::string package_name_;
Task::Id task_; Task::Id task_;
Stack::Id stack_;
}; };
} // namespace wm } // namespace wm