Restructure window creation and mangement
This commit is contained in:
parent
fee19cc627
commit
d4b4a795c3
28 changed files with 398 additions and 506 deletions
|
|
@ -103,17 +103,14 @@ set(SOURCES
|
|||
|
||||
anbox/graphics/opengles_message_processor.cpp
|
||||
anbox/graphics/gl_renderer_server.cpp
|
||||
anbox/graphics/window_creator.cpp
|
||||
anbox/graphics/density.h
|
||||
anbox/graphics/rect.cpp
|
||||
|
||||
anbox/graphics/emugl/ColorBuffer.cpp
|
||||
anbox/graphics/emugl/DisplayManager.cpp
|
||||
anbox/graphics/emugl/RendererConfig.cpp
|
||||
anbox/graphics/emugl/Renderable.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/RenderApi.cpp
|
||||
anbox/graphics/emugl/RenderContext.cpp
|
||||
|
|
@ -132,6 +129,7 @@ set(SOURCES
|
|||
|
||||
anbox/wm/display.cpp
|
||||
anbox/wm/task.cpp
|
||||
anbox/wm/stack.cpp
|
||||
anbox/wm/manager.cpp
|
||||
anbox/wm/window_state.cpp
|
||||
anbox/wm/window.cpp
|
||||
|
|
@ -158,9 +156,9 @@ set(SOURCES
|
|||
anbox/bridge/platform_api_skeleton.cpp
|
||||
anbox/bridge/android_api_stub.cpp
|
||||
|
||||
anbox/ubuntu/window_creator.cpp
|
||||
anbox/ubuntu/window.cpp
|
||||
anbox/ubuntu/keycode_converter.cpp
|
||||
anbox/ubuntu/platform_policy.cpp
|
||||
|
||||
anbox/dbus/interface.h
|
||||
anbox/dbus/skeleton/service.cpp
|
||||
|
|
|
|||
|
|
@ -51,12 +51,17 @@ void PlatformApiSkeleton::update_window_state(anbox::protobuf::bridge::WindowSta
|
|||
(void) response;
|
||||
|
||||
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(
|
||||
wm::Display::Id(window.display_id()),
|
||||
window.has_surface(),
|
||||
graphics::Rect(window.frame_left(), window.frame_top(), window.frame_right(), window.frame_bottom()),
|
||||
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;
|
||||
|
|
@ -68,7 +73,7 @@ void PlatformApiSkeleton::update_window_state(anbox::protobuf::bridge::WindowSta
|
|||
wm::WindowState::List removed;
|
||||
for (int n = 0; n < request->removed_windows_size(); 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);
|
||||
|
|
|
|||
|
|
@ -33,11 +33,10 @@
|
|||
#include "anbox/bridge/platform_message_processor.h"
|
||||
#include "anbox/bridge/android_api_stub.h"
|
||||
#include "anbox/bridge/platform_api_skeleton.h"
|
||||
#include "anbox/ubuntu/window_creator.h"
|
||||
#include "anbox/dbus/skeleton/service.h"
|
||||
#include "anbox/container/client.h"
|
||||
#include "anbox/wm/manager.h"
|
||||
#include "anbox/wm/default_platform_policy.h"
|
||||
#include "anbox/ubuntu/platform_policy.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 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_creator = std::make_shared<ubuntu::WindowCreator>(input_manager);
|
||||
auto renderer = std::make_shared<graphics::GLRendererServer>(window_creator);
|
||||
auto renderer = std::make_shared<graphics::GLRendererServer>();
|
||||
renderer->start();
|
||||
|
||||
// Socket which will be used by the qemud service inside the Android
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
|
||||
class TextureDraw;
|
||||
class TextureResize;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -20,7 +20,6 @@
|
|||
#include "Renderer.h"
|
||||
#include "RenderThreadInfo.h"
|
||||
#include "ChecksumCalculatorThreadInfo.h"
|
||||
#include "LayerManager.h"
|
||||
#include "DisplayManager.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 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()
|
||||
{
|
||||
LayerManager::get()->finish_cycle();
|
||||
void rcPostAllLayersDone() {
|
||||
}
|
||||
|
||||
void initRenderControlContext(renderControl_decoder_context_t *dec)
|
||||
|
|
|
|||
38
src/anbox/graphics/emugl/Renderable.cpp
Normal file
38
src/anbox/graphics/emugl/Renderable.cpp
Normal 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_;
|
||||
}
|
||||
43
src/anbox/graphics/emugl/Renderable.h
Normal file
43
src/anbox/graphics/emugl/Renderable.h
Normal 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
|
||||
|
|
@ -17,7 +17,6 @@
|
|||
#include "Renderer.h"
|
||||
|
||||
#include "DispatchTables.h"
|
||||
#include "NativeSubWindow.h"
|
||||
#include "RenderThreadInfo.h"
|
||||
#include "TimeUtils.h"
|
||||
#include "gles2_dec.h"
|
||||
|
|
@ -456,40 +455,32 @@ Renderer::~Renderer() {
|
|||
struct RendererWindow {
|
||||
EGLNativeWindowType native_window = 0;
|
||||
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();
|
||||
|
||||
auto native_window = createSubWindow(0, x, y, width, height);
|
||||
if (!native_window) {
|
||||
m_lock.unlock();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto window = new RendererWindow;
|
||||
window->native_window = native_window;
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
|
||||
window->surface = s_egl.eglCreateWindowSurface(
|
||||
m_eglDisplay, m_eglConfig, window->native_window, nullptr);
|
||||
if (window->surface == EGL_NO_SURFACE) {
|
||||
destroyWindow(window);
|
||||
if (window->surface == EGL_NO_SURFACE)
|
||||
{
|
||||
delete window;
|
||||
m_lock.unlock();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!bindWindow_locked(window)) {
|
||||
destroyWindow(window);
|
||||
if (!bindWindow_locked(window))
|
||||
{
|
||||
s_egl.eglDestroySurface(m_eglDisplay, window->surface);
|
||||
delete window;
|
||||
m_lock.unlock();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
s_gles2.glViewport(0, 0, width, height);
|
||||
// s_gles2.glViewport(0, 0, width, height);
|
||||
s_gles2.glClear(GL_COLOR_BUFFER_BIT |
|
||||
GL_DEPTH_BUFFER_BIT |
|
||||
GL_STENCIL_BUFFER_BIT);
|
||||
|
|
@ -497,35 +488,27 @@ RendererWindow* Renderer::createWindow(int x, int y, int width, int height) {
|
|||
|
||||
unbind_locked();
|
||||
|
||||
m_nativeWindows.insert({native_window, window});
|
||||
|
||||
m_lock.unlock();
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void Renderer::updateWindow(RendererWindow *window, int x, int y, int width, int height) {
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
updateSubWindow(window->native_window, x, y, width, height);
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
window->needViewportUpdate = true;
|
||||
}
|
||||
|
||||
void Renderer::destroyWindow(RendererWindow *window) {
|
||||
if (!window)
|
||||
void Renderer::destroyNativeWindow(EGLNativeWindowType native_window) {
|
||||
auto w = m_nativeWindows.find(native_window);
|
||||
if (w == m_nativeWindows.end())
|
||||
return;
|
||||
|
||||
m_lock.lock();
|
||||
|
||||
s_egl.eglMakeCurrent(m_eglDisplay, nullptr, nullptr, nullptr);
|
||||
|
||||
if (window->surface != EGL_NO_SURFACE)
|
||||
s_egl.eglDestroySurface(m_eglDisplay, window->surface);
|
||||
if (w->second->surface != EGL_NO_SURFACE)
|
||||
s_egl.eglDestroySurface(m_eglDisplay, w->second->surface);
|
||||
|
||||
destroySubWindow(window->native_window);
|
||||
|
||||
delete window;
|
||||
delete w->second;
|
||||
m_nativeWindows.erase(w);
|
||||
|
||||
m_lock.unlock();
|
||||
}
|
||||
|
|
@ -990,10 +973,12 @@ bool Renderer::post(RendererWindow *window, HandleType p_colorbuffer, bool needL
|
|||
if (!bindWindow_locked(window))
|
||||
goto EXIT;
|
||||
|
||||
#if 0
|
||||
if (window->needViewportUpdate) {
|
||||
s_gles2.glViewport(0, 0, window->width, window->height);
|
||||
window->needViewportUpdate = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
s_gles2.glClearColor(0.0, 0.0, 1.0, 0.0);
|
||||
s_gles2.glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
|
@ -1029,3 +1014,39 @@ EXIT:
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
|
||||
#include "OpenglRender/render_api.h"
|
||||
|
||||
#include "Renderable.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <map>
|
||||
|
|
@ -78,10 +80,6 @@ public:
|
|||
// Returns true on success, false otherwise.
|
||||
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.
|
||||
void finalize();
|
||||
|
||||
|
|
@ -111,6 +109,10 @@ public:
|
|||
*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.
|
||||
// |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.
|
||||
|
|
@ -234,6 +236,8 @@ public:
|
|||
// false only when called internally.
|
||||
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.
|
||||
EGLDisplay getDisplay() const { return m_eglDisplay; }
|
||||
|
||||
|
|
@ -286,5 +290,7 @@ private:
|
|||
const char* m_glVendor;
|
||||
const char* m_glRenderer;
|
||||
const char* m_glVersion;
|
||||
|
||||
std::map<EGLNativeWindowType,RendererWindow*> m_nativeWindows;
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include "anbox/logger.h"
|
||||
#include "anbox/graphics/gl_renderer_server.h"
|
||||
#include "anbox/graphics/window_creator.h"
|
||||
|
||||
#include "OpenglRender/render_api.h"
|
||||
|
||||
|
|
@ -27,8 +26,8 @@
|
|||
|
||||
namespace anbox {
|
||||
namespace graphics {
|
||||
GLRendererServer::GLRendererServer(const std::shared_ptr<WindowCreator> &window_creator) :
|
||||
window_creator_(window_creator) {
|
||||
GLRendererServer::GLRendererServer()
|
||||
{
|
||||
|
||||
if (utils::is_env_set("USE_HOST_GLES")) {
|
||||
// Force the host EGL/GLES libraries as translator implementation
|
||||
|
|
@ -44,13 +43,9 @@ GLRendererServer::GLRendererServer(const std::shared_ptr<WindowCreator> &window_
|
|||
|
||||
if (!initLibrary())
|
||||
BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize OpenGL renderer"));
|
||||
|
||||
registerSubWindowHandler(window_creator_);
|
||||
registerDisplayManager(window_creator_);
|
||||
}
|
||||
|
||||
GLRendererServer::~GLRendererServer() {
|
||||
// destroyOpenGLSubwindow();
|
||||
stopOpenGLRenderer();
|
||||
}
|
||||
|
||||
|
|
@ -70,15 +65,11 @@ void GLRendererServer::start() {
|
|||
log_funcs.coarse = 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 };
|
||||
// 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
|
||||
// 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"));
|
||||
|
||||
socket_path_ = server_addr;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ namespace graphics {
|
|||
class WindowCreator;
|
||||
class GLRendererServer {
|
||||
public:
|
||||
GLRendererServer(const std::shared_ptr<WindowCreator> &window_creator);
|
||||
GLRendererServer();
|
||||
~GLRendererServer();
|
||||
|
||||
void start();
|
||||
|
|
@ -38,7 +38,6 @@ public:
|
|||
|
||||
private:
|
||||
std::string socket_path_;
|
||||
std::shared_ptr<WindowCreator> window_creator_;
|
||||
};
|
||||
|
||||
} // namespace graphics
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "anbox/ubuntu/window_creator.h"
|
||||
#include "anbox/ubuntu/platform_policy.h"
|
||||
#include "anbox/ubuntu/window.h"
|
||||
#include "anbox/ubuntu/keycode_converter.h"
|
||||
#include "anbox/input/manager.h"
|
||||
|
|
@ -29,16 +29,14 @@
|
|||
|
||||
namespace anbox {
|
||||
namespace ubuntu {
|
||||
WindowCreator::WindowCreator(const std::shared_ptr<input::Manager> &input_manager) :
|
||||
graphics::WindowCreator(input_manager),
|
||||
PlatformPolicy::PlatformPolicy(const std::shared_ptr<input::Manager> &input_manager) :
|
||||
input_manager_(input_manager),
|
||||
event_thread_running_(false),
|
||||
display_info_({1920, 1080}) {
|
||||
event_thread_running_(false) {
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0)
|
||||
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;
|
||||
// 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);
|
||||
}
|
||||
|
||||
WindowCreator::~WindowCreator() {
|
||||
PlatformPolicy::~PlatformPolicy() {
|
||||
event_thread_running_ = false;
|
||||
event_thread_.join();
|
||||
}
|
||||
|
||||
void WindowCreator::process_events() {
|
||||
void PlatformPolicy::process_events() {
|
||||
event_thread_running_ = true;
|
||||
|
||||
while(event_thread_running_) {
|
||||
|
|
@ -90,9 +88,11 @@ void WindowCreator::process_events() {
|
|||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
for (auto &iter : windows_) {
|
||||
if (iter.second->id() == event.window.windowID) {
|
||||
iter.second->process_event(event);
|
||||
break;
|
||||
if (auto w = iter.second.lock()) {
|
||||
if (w->window_id() == event.window.windowID) {
|
||||
w->process_event(event);
|
||||
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> keyboard_events;
|
||||
|
||||
|
|
@ -176,44 +176,29 @@ void WindowCreator::process_input_event(const SDL_Event &event) {
|
|||
keyboard_->send_events(keyboard_events);
|
||||
}
|
||||
|
||||
EGLNativeWindowType WindowCreator::create_window(int x, int y, int width, int height)
|
||||
try {
|
||||
auto window = std::make_shared<Window>(x, y, width, height);
|
||||
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;
|
||||
Window::Id PlatformPolicy::next_window_id() {
|
||||
static Window::Id next_id = 0;
|
||||
return next_id++;
|
||||
}
|
||||
|
||||
void WindowCreator::update_window(EGLNativeWindowType win, int x, int y, int width, int height) {
|
||||
auto iter = windows_.find(win);
|
||||
if (iter == windows_.end())
|
||||
std::shared_ptr<wm::Window> PlatformPolicy::create_window(const wm::WindowState &state) {
|
||||
auto id = next_window_id();
|
||||
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;
|
||||
|
||||
iter->second->resize(width, height);
|
||||
iter->second->update_position(x, y);
|
||||
}
|
||||
windows_.erase(w);
|
||||
}
|
||||
|
||||
void WindowCreator::destroy_window(EGLNativeWindowType win) {
|
||||
auto iter = windows_.find(win);
|
||||
if (iter == windows_.end())
|
||||
return;
|
||||
|
||||
windows_.erase(iter);
|
||||
}
|
||||
|
||||
WindowCreator::DisplayInfo WindowCreator::display_info() const {
|
||||
DisplayManager::DisplayInfo PlatformPolicy::display_info() const {
|
||||
return display_info_;
|
||||
}
|
||||
|
||||
EGLNativeDisplayType WindowCreator::native_display() const {
|
||||
return 0;
|
||||
}
|
||||
} // namespace bridge
|
||||
} // namespace wm
|
||||
} // namespace anbox
|
||||
|
|
@ -15,15 +15,17 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_UBUNTU_WINDOW_CREATOR_H_
|
||||
#define ANBOX_UBUNTU_WINDOW_CREATOR_H_
|
||||
#ifndef ANBOX_UBUNTU_PLATFORM_POLICY_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 <map>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <SDL.h>
|
||||
|
||||
namespace anbox {
|
||||
|
|
@ -32,34 +34,38 @@ class Device;
|
|||
class Manager;
|
||||
} // namespace input
|
||||
namespace ubuntu {
|
||||
class MirDisplayConnection;
|
||||
class Window;
|
||||
class WindowCreator : public graphics::WindowCreator {
|
||||
class PlatformPolicy : public std::enable_shared_from_this<PlatformPolicy>,
|
||||
public wm::PlatformPolicy,
|
||||
public Window::Observer,
|
||||
public DisplayManager {
|
||||
public:
|
||||
WindowCreator(const std::shared_ptr<input::Manager> &input_manager);
|
||||
~WindowCreator();
|
||||
PlatformPolicy(const std::shared_ptr<input::Manager> &input_manager);
|
||||
~PlatformPolicy();
|
||||
|
||||
EGLNativeWindowType create_window(int x, int y, int width, int height) override;
|
||||
void update_window(EGLNativeWindowType win, int x, int y, int width, int height) override;
|
||||
void destroy_window(EGLNativeWindowType win) override;
|
||||
std::shared_ptr<wm::Window> create_window(const wm::WindowState &state) override;
|
||||
|
||||
void window_deleted(const Window::Id &id) override;
|
||||
|
||||
DisplayInfo display_info() const override;
|
||||
EGLNativeDisplayType native_display() const override;
|
||||
|
||||
private:
|
||||
void process_events();
|
||||
void process_input_event(const SDL_Event &event);
|
||||
|
||||
static Window::Id next_window_id();
|
||||
|
||||
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::thread event_thread_;
|
||||
bool event_thread_running_;
|
||||
graphics::WindowCreator::DisplayInfo display_info_;
|
||||
std::shared_ptr<input::Device> pointer_;
|
||||
std::shared_ptr<input::Device> keyboard_;
|
||||
DisplayManager::DisplayInfo display_info_;
|
||||
};
|
||||
} // namespace ubuntu
|
||||
} // namespace wm
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
|
|
@ -16,15 +16,69 @@
|
|||
*/
|
||||
|
||||
#include "anbox/ubuntu/window.h"
|
||||
#include "anbox/wm/window_state.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
#include <SDL_syswm.h>
|
||||
|
||||
namespace {
|
||||
constexpr const char* default_window_name{"anbox"};
|
||||
}
|
||||
|
||||
namespace anbox {
|
||||
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) :
|
||||
wm::Window(wm::WindowState()),
|
||||
native_display_(0),
|
||||
native_window_(0) {
|
||||
|
||||
|
|
@ -60,6 +114,9 @@ Window::Window(int x, int y, int width, int height) :
|
|||
Window::~Window() {
|
||||
if (window_)
|
||||
SDL_DestroyWindow(window_);
|
||||
|
||||
if (observer_)
|
||||
observer_->window_deleted(id_);
|
||||
}
|
||||
|
||||
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_;
|
||||
}
|
||||
|
||||
std::uint32_t Window::id() const {
|
||||
Window::Id Window::id() const {
|
||||
return id_;
|
||||
}
|
||||
|
||||
std::uint32_t Window::window_id() const {
|
||||
return SDL_GetWindowID(window_);
|
||||
}
|
||||
} // namespace bridge
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
#ifndef ANBOX_UBUNTU_WINDOW_H_
|
||||
#define ANBOX_UBUNTU_WINDOW_H_
|
||||
|
||||
#include "anbox/wm/window.h"
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <memory>
|
||||
|
|
@ -27,8 +29,19 @@
|
|||
|
||||
namespace anbox {
|
||||
namespace ubuntu {
|
||||
class Window {
|
||||
class Window : public std::enable_shared_from_this<Window>,
|
||||
public wm::Window {
|
||||
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();
|
||||
|
||||
|
|
@ -37,10 +50,13 @@ public:
|
|||
|
||||
void process_event(const SDL_Event &event);
|
||||
|
||||
EGLNativeWindowType native_window() const;
|
||||
std::uint32_t id() const;
|
||||
EGLNativeWindowType native_handle() const override;
|
||||
Id id() const;
|
||||
std::uint32_t window_id() const;
|
||||
|
||||
private:
|
||||
Id id_;
|
||||
std::shared_ptr<Observer> observer_;
|
||||
EGLNativeDisplayType native_display_;
|
||||
EGLNativeWindowType native_window_;
|
||||
SDL_Window *window_;
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@
|
|||
|
||||
#include "anbox/wm/default_platform_policy.h"
|
||||
#include "anbox/wm/window.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
namespace {
|
||||
class Window : public anbox::wm::Window {
|
||||
class NullWindow : public anbox::wm::Window {
|
||||
public:
|
||||
Window(const anbox::wm::WindowState &state) :
|
||||
NullWindow(const anbox::wm::WindowState &state) :
|
||||
anbox::wm::Window(state) {
|
||||
}
|
||||
};
|
||||
|
|
@ -32,8 +33,10 @@ namespace wm {
|
|||
DefaultPlatformPolicy::DefaultPlatformPolicy() {
|
||||
}
|
||||
|
||||
std::shared_ptr<Window> DefaultPlatformPolicy::create_window(const WindowState &state) {
|
||||
return std::make_shared<::Window>(state);
|
||||
std::shared_ptr<Window> DefaultPlatformPolicy::create_window(const WindowState &state)
|
||||
{
|
||||
DEBUG("");
|
||||
return std::make_shared<::NullWindow>(state);
|
||||
}
|
||||
} // namespace wm
|
||||
} // namespace anbox
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "anbox/wm/manager.h"
|
||||
#include "anbox/wm/platform_policy.h"
|
||||
#include "anbox/logger.h"
|
||||
|
||||
namespace anbox {
|
||||
|
|
@ -28,11 +29,39 @@ Manager::~Manager() {
|
|||
}
|
||||
|
||||
void Manager::apply_window_state_update(const WindowState::List &updated,
|
||||
const WindowState::List &removed) {
|
||||
(void) updated;
|
||||
(void) removed;
|
||||
|
||||
const WindowState::List &removed)
|
||||
{
|
||||
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 anbox
|
||||
|
|
|
|||
|
|
@ -19,8 +19,10 @@
|
|||
#define ANBOX_WM_MANAGER_H_
|
||||
|
||||
#include "anbox/wm/window_state.h"
|
||||
#include "anbox/wm/window.h"
|
||||
|
||||
#include <memory>
|
||||
#include <map>
|
||||
|
||||
namespace anbox {
|
||||
namespace wm {
|
||||
|
|
@ -35,6 +37,7 @@ public:
|
|||
|
||||
private:
|
||||
std::shared_ptr<PlatformPolicy> platform_;
|
||||
std::map<Task::Id, std::shared_ptr<Window>> windows_;
|
||||
};
|
||||
} // namespace wm
|
||||
} // namespace anbox
|
||||
|
|
|
|||
|
|
@ -15,16 +15,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include "anbox/graphics/window_creator.h"
|
||||
|
||||
#include "anbox/wm/stack.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace graphics {
|
||||
WindowCreator::WindowCreator(const std::shared_ptr<input::Manager> &input_manager) :
|
||||
input_manager_(input_manager) {
|
||||
}
|
||||
|
||||
WindowCreator::~WindowCreator() {
|
||||
}
|
||||
} // namespace graphics
|
||||
namespace wm {
|
||||
Stack::Id Stack::Invalid = -1;
|
||||
Stack::Id Stack::Default = 0;
|
||||
Stack::Id Stack::Fullscreen = 1;
|
||||
Stack::Id Stack::Freeform = 2;
|
||||
} // namespace wm
|
||||
} // namespace anbox
|
||||
|
|
@ -15,28 +15,26 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef ANBOX_GRAPHICS_WINDOW_CREATOR_H_
|
||||
#define ANBOX_GRAPHICS_WINDOW_CREATOR_H_
|
||||
#ifndef ANBOX_WM_STACK_H_
|
||||
#define ANBOX_WM_STACK_H_
|
||||
|
||||
#include "anbox/graphics/emugl/NativeSubWindow.h"
|
||||
#include "anbox/graphics/emugl/DisplayManager.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace anbox {
|
||||
namespace input {
|
||||
class Manager;
|
||||
} // namespace input
|
||||
namespace graphics {
|
||||
class WindowCreator : public SubWindowHandler,
|
||||
public DisplayManager {
|
||||
namespace wm {
|
||||
class Stack {
|
||||
public:
|
||||
WindowCreator(const std::shared_ptr<input::Manager> &input_manager);
|
||||
virtual ~WindowCreator();
|
||||
typedef std::int32_t Id;
|
||||
|
||||
virtual EGLNativeDisplayType native_display() const = 0;
|
||||
static Id Invalid;
|
||||
static Id Default;
|
||||
static Id Fullscreen;
|
||||
static Id Freeform;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<input::Manager> input_manager_;
|
||||
Stack() = delete;
|
||||
Stack(const Stack&) = delete;
|
||||
};
|
||||
} // namespace graphics
|
||||
} // namespace wm
|
||||
} // namespace anbox
|
||||
|
||||
#endif
|
||||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
|
||||
#include "anbox/wm/window.h"
|
||||
#include "anbox/graphics/emugl/Renderer.h"
|
||||
|
||||
namespace anbox {
|
||||
namespace wm {
|
||||
|
|
@ -30,8 +31,16 @@ void Window::update_state(const WindowState &state) {
|
|||
state_ = state;
|
||||
}
|
||||
|
||||
void Window::render_layer(const Layer &layer) {
|
||||
(void) layer;
|
||||
EGLNativeWindowType Window::native_handle() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Window::attach() {
|
||||
return Renderer::get()->createNativeWindow(native_handle());
|
||||
}
|
||||
|
||||
void Window::release() {
|
||||
Renderer::get()->destroyNativeWindow(native_handle());
|
||||
}
|
||||
} // namespace wm
|
||||
} // namespace anbox
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
namespace anbox {
|
||||
namespace wm {
|
||||
// FIXME(morphis): move this somewhere else once we have the integration
|
||||
|
|
@ -35,19 +37,20 @@ private:
|
|||
graphics::Rect frame_;
|
||||
};
|
||||
|
||||
class Window {
|
||||
class Window
|
||||
{
|
||||
public:
|
||||
typedef std::vector<Window> List;
|
||||
|
||||
Window(const WindowState &state);
|
||||
virtual ~Window();
|
||||
|
||||
bool attach();
|
||||
void release();
|
||||
|
||||
void update_state(const WindowState &state);
|
||||
|
||||
// Render a layer into the window. The layer itself includes all
|
||||
// necessary information for correct rendering.
|
||||
void render_layer(const Layer &layer);
|
||||
|
||||
virtual EGLNativeWindowType native_handle() const;
|
||||
WindowState state() const;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -24,19 +24,22 @@ WindowState::WindowState() :
|
|||
has_surface_(false),
|
||||
frame_(graphics::Rect::Invalid),
|
||||
package_name_(""),
|
||||
task_(Task::Invalid) {
|
||||
task_(Task::Invalid),
|
||||
stack_(Stack::Invalid) {
|
||||
}
|
||||
|
||||
WindowState::WindowState(const Display::Id &display,
|
||||
bool has_surface,
|
||||
const graphics::Rect &frame,
|
||||
const std::string &package_name,
|
||||
const Task::Id &task) :
|
||||
const Task::Id &task,
|
||||
const Stack::Id &stack) :
|
||||
display_(display),
|
||||
has_surface_(has_surface),
|
||||
frame_(frame),
|
||||
package_name_(package_name),
|
||||
task_(task) {
|
||||
task_(task),
|
||||
stack_(stack) {
|
||||
}
|
||||
|
||||
WindowState::~WindowState() {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "anbox/graphics/rect.h"
|
||||
#include "anbox/wm/display.h"
|
||||
#include "anbox/wm/task.h"
|
||||
#include "anbox/wm/stack.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
|
@ -36,7 +37,8 @@ public:
|
|||
bool has_surface,
|
||||
const graphics::Rect &frame,
|
||||
const std::string &package_name,
|
||||
const Task::Id &task);
|
||||
const Task::Id &task,
|
||||
const Stack::Id &stack);
|
||||
~WindowState();
|
||||
|
||||
Display::Id display() const { return display_; }
|
||||
|
|
@ -44,6 +46,7 @@ public:
|
|||
graphics::Rect frame() const { return frame_; }
|
||||
std::string package_name() const { return package_name_; }
|
||||
Task::Id task() const { return task_; }
|
||||
Stack::Id stack() const { return stack_; }
|
||||
|
||||
private:
|
||||
Display::Id display_;
|
||||
|
|
@ -51,6 +54,7 @@ private:
|
|||
graphics::Rect frame_;
|
||||
std::string package_name_;
|
||||
Task::Id task_;
|
||||
Stack::Id stack_;
|
||||
|
||||
};
|
||||
} // namespace wm
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue