diff --git a/android/app_manager/Android.mk b/android/app_manager/Android.mk index bd37d100e777bc76d26368bca757cf4b490d39c2..8b1a3b8416c24d9e9e617da8321d0027547ee967 100644 --- a/android/app_manager/Android.mk +++ b/android/app_manager/Android.mk @@ -6,6 +6,8 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := AnboxAppManager LOCAL_CERTIFICATE := platform LOCAL_PRIVILEGED_MODULE := true +# We kick out several core packages here which would +# otherwise put up the base UI we don't want. LOCAL_OVERRIDES_PACKAGES := \ Home \ Launcher2 \ diff --git a/android/hwcomposer/hwcomposer.cpp b/android/hwcomposer/hwcomposer.cpp index d501029d59381afb901f8940ba5002e33767317c..38d8c4aec50b10ddf8073b96d5b3f28175e7ed8e 100644 --- a/android/hwcomposer/hwcomposer.cpp +++ b/android/hwcomposer/hwcomposer.cpp @@ -18,6 +18,11 @@ #include #include +#include +#include +#include +#include + #define LOG_NDEBUG 0 #include @@ -67,8 +72,8 @@ struct HwcContext { }; static void dump_layer(hwc_layer_1_t const* l) { - ALOGI("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}", - l->compositionType, l->flags, l->handle, l->transform, l->blending, + ALOGI("\tname='%s', type=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}", + l->name, l->compositionType, l->flags, l->handle, l->transform, l->blending, l->sourceCrop.left, l->sourceCrop.top, l->sourceCrop.right, @@ -185,11 +190,22 @@ static int hwc_set(hwc_composer_device_1_t* dev, size_t numDisplays, return -EINVAL; } - ALOGI("Posting buffer %p\n", cb->hostHandle); - rcEnc->rcFBPost(rcEnc, cb->hostHandle); + rcEnc->rcPostLayer(rcEnc, + layer->name, + cb->hostHandle, + layer->sourceCrop.left, + layer->sourceCrop.top, + layer->sourceCrop.right, + layer->sourceCrop.bottom, + layer->displayFrame.left, + layer->displayFrame.top, + layer->displayFrame.right, + layer->displayFrame.bottom); hostCon->flush(); } + rcEnc->rcPostAllLayersDone(rcEnc); + check_sync_fds(numDisplays, displays); return 0; @@ -226,8 +242,64 @@ static int hwc_device_close(hw_device_t* dev) { return 0; } +static int hwc_get_display_configs(hwc_composer_device_1* dev, int disp, + uint32_t* configs, size_t* numConfigs) { + ALOGI("%s", __PRETTY_FUNCTION__); + + if (disp != 0) { + return -EINVAL; + } + + if (*numConfigs > 0) { + // Config[0] will be passed in to getDisplayAttributes as the disp + // parameter. The ARC display supports only 1 configuration. + configs[0] = 0; + *numConfigs = 1; + } + return 0; +} + +static int hwc_get_display_attributes(hwc_composer_device_1* dev, + int disp, uint32_t config, + const uint32_t* attributes, + int32_t* values) { + ALOGI("%s", __PRETTY_FUNCTION__); + + if (disp != 0 || config != 0) { + return -EINVAL; + } + + DEFINE_AND_VALIDATE_HOST_CONNECTION(); + + while (*attributes != HWC_DISPLAY_NO_ATTRIBUTE) { + switch (*attributes) { + case HWC_DISPLAY_VSYNC_PERIOD: + *values = rcEnc->rcGetDisplayVsyncPeriod(rcEnc, disp); + break; + case HWC_DISPLAY_WIDTH: + *values = rcEnc->rcGetDisplayWidth(rcEnc, disp); + break; + case HWC_DISPLAY_HEIGHT: + *values = rcEnc->rcGetDisplayHeight(rcEnc, disp); + break; + case HWC_DISPLAY_DPI_X: + *values = 1000 * rcEnc->rcGetDisplayDpiX(rcEnc, disp); + break; + case HWC_DISPLAY_DPI_Y: + *values = 1000 * rcEnc->rcGetDisplayDpiY(rcEnc, disp); + break; + default: + ALOGE("Unknown attribute value 0x%02x", *attributes); + } + ++attributes; + ++values; + } + return 0; +} + static int hwc_device_open(const hw_module_t* module, const char* name, hw_device_t** device) { ALOGI("%s", __PRETTY_FUNCTION__); + if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) return -EINVAL; @@ -241,9 +313,9 @@ static int hwc_device_open(const hw_module_t* module, const char* name, hw_devic dev->device.eventControl = hwc_event_control; dev->device.blank = hwc_blank; dev->device.query = hwc_query; + dev->device.getDisplayConfigs = hwc_get_display_configs; + dev->device.getDisplayAttributes = hwc_get_display_attributes; dev->device.registerProcs = hwc_register_procs; - // FIXME: eventually implement to dump specific information - dev->device.dump = nullptr; *device = &dev->device.common; diff --git a/external/android-emugl/host/libs/libOpenglRender/CMakeLists.txt b/external/android-emugl/host/libs/libOpenglRender/CMakeLists.txt index 7a25973cf825ebcbb1d60850fa8bf5ac8bfe96ee..bbf5b9aca79303e70503f58421ba094c9c598add 100644 --- a/external/android-emugl/host/libs/libOpenglRender/CMakeLists.txt +++ b/external/android-emugl/host/libs/libOpenglRender/CMakeLists.txt @@ -2,6 +2,7 @@ set(SOURCES ColorBuffer.cpp FbConfig.cpp FrameBuffer.cpp + LayerManager.cpp NativeSubWindow_delegate.cpp ReadBuffer.cpp RenderContext.cpp @@ -9,7 +10,7 @@ set(SOURCES RenderServer.cpp RenderThread.cpp RenderThreadInfo.cpp - render_api.cpp + RenderApi.cpp RenderWindow.cpp SocketStream.cpp TcpStream.cpp diff --git a/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.cpp b/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.cpp index bff43b34c3b29775c03da34c9663d7e00c407750..b81e68e9980f35f4291374372b654c1919cb352a 100644 --- a/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.cpp +++ b/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.cpp @@ -154,9 +154,6 @@ static char* getGLES1ExtensionString(EGLDisplay p_dpy) void FrameBuffer::finalize(){ m_colorbuffers.clear(); - if (m_useSubWindow) { - removeSubWindow(); - } m_windows.clear(); m_contexts.clear(); s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL); @@ -431,32 +428,19 @@ bool FrameBuffer::initialize(EGLNativeDisplayType nativeDisplay, int width, int } FrameBuffer::FrameBuffer(int p_width, int p_height, bool useSubWindow) : - m_framebufferWidth(p_width), - m_framebufferHeight(p_height), - m_windowWidth(p_width), - m_windowHeight(p_height), m_useSubWindow(useSubWindow), m_configs(NULL), m_eglDisplay(EGL_NO_DISPLAY), m_colorBufferHelper(new ColorBufferHelper(this)), - m_eglSurface(EGL_NO_SURFACE), m_eglContext(EGL_NO_CONTEXT), m_pbufContext(EGL_NO_CONTEXT), m_prevContext(EGL_NO_CONTEXT), m_prevReadSurf(EGL_NO_SURFACE), m_prevDrawSurf(EGL_NO_SURFACE), - m_subWin((EGLNativeWindowType)0), m_textureDraw(NULL), m_lastPostedColorBuffer(0), - m_zRot(0.0f), - m_px(0), - m_py(0), - m_eglContextInitialized(false), m_statsNumFrames(0), m_statsStartTime(0LL), - m_onPost(NULL), - m_onPostContext(NULL), - m_fbImage(NULL), m_glVendor(NULL), m_glRenderer(NULL), m_glVersion(NULL) @@ -468,147 +452,68 @@ FrameBuffer::~FrameBuffer() { delete m_textureDraw; delete m_configs; delete m_colorBufferHelper; - free(m_fbImage); -} - -void FrameBuffer::setPostCallback(OnPostFn onPost, void* onPostContext) -{ - emugl::Mutex::AutoLock mutex(m_lock); - m_onPost = onPost; - m_onPostContext = onPostContext; - if (m_onPost && !m_fbImage) { - m_fbImage = (unsigned char*)malloc(4 * m_framebufferWidth * m_framebufferHeight); - if (!m_fbImage) { - ERR("out of memory, cancelling OnPost callback"); - m_onPost = NULL; - m_onPostContext = NULL; - return; - } - } } -static void subWindowRepaint(void* param) { - auto fb = static_cast(param); - fb->repost(); -} - -bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window, - int wx, - int wy, - int ww, - int wh, - int fbw, - int fbh, - float dpr, - float zRot) { - bool success = false; - - if (!m_useSubWindow) { - ERR("%s: Cannot create native sub-window in this configuration\n", - __FUNCTION__); - return false; - } +struct FrameBufferWindow { + EGLNativeWindowType native_window = 0; + EGLSurface surface = EGL_NO_SURFACE; +}; +FrameBufferWindow* FrameBuffer::createWindow(int x, int y, int width, int height) { m_lock.lock(); - // If the subwindow doesn't exist, create it with the appropriate dimensions - if (!m_subWin) { - - // Create native subwindow for FB display output - m_x = wx; - m_y = wy; - m_windowWidth = ww; - m_windowHeight = wh; - - m_subWin = createSubWindow(p_window, m_x, m_y, - m_windowWidth, m_windowHeight, subWindowRepaint, this); - if (m_subWin) { - m_nativeWindow = p_window; - - // create EGLSurface from the generated subwindow - m_eglSurface = s_egl.eglCreateWindowSurface(m_eglDisplay, - m_eglConfig, - m_subWin, - NULL); - - if (m_eglSurface == EGL_NO_SURFACE) { - // NOTE: This can typically happen with software-only renderers like OSMesa. - destroySubWindow(m_subWin); - m_subWin = (EGLNativeWindowType)0; - } else { - m_px = 0; - m_py = 0; - - success = true; - } - } + auto native_window = createSubWindow(0, x, y, width, height); + if (!native_window) { + m_lock.unlock(); + return nullptr; } - // At this point, if the subwindow doesn't exist, it is because it either couldn't be created - // in the first place or the EGLSurface couldn't be created. - if (m_subWin && bindSubwin_locked()) { + auto window = new FrameBufferWindow; + window->native_window = native_window; - // Only attempt to update window geometry if anything has actually changed. - if (!(m_x == wx && - m_y == wy && - m_windowWidth == ww && - m_windowHeight == wh)) { + window->surface = s_egl.eglCreateWindowSurface( + m_eglDisplay, m_eglConfig, window->native_window, nullptr); + if (window->surface == EGL_NO_SURFACE) { + destroyWindow(window); + m_lock.unlock(); + return nullptr; + } - m_x = wx; - m_y = wy; - m_windowWidth = ww; - m_windowHeight = wh; + if (!bindWindow_locked(window)) { + destroyWindow(window); + m_lock.unlock(); + return nullptr; + } - success = ::moveSubWindow(m_nativeWindow, m_subWin, - m_x, m_y, m_windowWidth, m_windowHeight); + s_gles2.glViewport(0, 0, width, height); + s_gles2.glClear(GL_COLOR_BUFFER_BIT | + GL_DEPTH_BUFFER_BIT | + GL_STENCIL_BUFFER_BIT); + s_egl.eglSwapBuffers(m_eglDisplay, window->surface); - // Otherwise, ensure that at least viewport parameters are properly updated. - } else { - success = true; - } - - if (success) { - // Subwin creation or movement was successful, - // update viewport and z rotation and draw - // the last posted color buffer. - s_gles2.glViewport(0, 0, fbw * dpr, fbh * dpr); - m_dpr = dpr; - m_zRot = zRot; - if (m_lastPostedColorBuffer) { - post(m_lastPostedColorBuffer, false); - } else { - s_gles2.glClear(GL_COLOR_BUFFER_BIT | - GL_DEPTH_BUFFER_BIT | - GL_STENCIL_BUFFER_BIT); - s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface); - } - } - unbind_locked(); - } + unbind_locked(); m_lock.unlock(); - return success; + + return window; } -bool FrameBuffer::removeSubWindow() { - if (!m_useSubWindow) { - ERR("%s: Cannot remove native sub-window in this configuration\n", - __FUNCTION__); - return false; - } - bool removed = false; +void FrameBuffer::destroyWindow(FrameBufferWindow *window) { + if (!window) + return; + m_lock.lock(); - if (m_subWin) { - s_egl.eglMakeCurrent(m_eglDisplay, NULL, NULL, NULL); - s_egl.eglDestroySurface(m_eglDisplay, m_eglSurface); - destroySubWindow(m_subWin); - m_eglSurface = EGL_NO_SURFACE; - m_subWin = (EGLNativeWindowType)0; - removed = true; - } + s_egl.eglMakeCurrent(m_eglDisplay, nullptr, nullptr, nullptr); + + if (window->surface != EGL_NO_SURFACE) + s_egl.eglDestroySurface(m_eglDisplay, window->surface); + + destroySubWindow(window->native_window); + + delete window; + m_lock.unlock(); - return removed; } HandleType FrameBuffer::genHandle() @@ -1021,25 +926,18 @@ bool FrameBuffer::bind_locked() return true; } -bool FrameBuffer::bindSubwin_locked() +bool FrameBuffer::bindWindow_locked(FrameBufferWindow *window) { EGLContext prevContext = s_egl.eglGetCurrentContext(); EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); - if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface, - m_eglSurface, m_eglContext)) { + if (!s_egl.eglMakeCurrent(m_eglDisplay, window->surface, + window->surface, m_eglContext)) { ERR("eglMakeCurrent failed\n"); return false; } - // - // initialize GL state in eglContext if not yet initilaized - // - if (!m_eglContextInitialized) { - m_eglContextInitialized = true; - } - m_prevContext = prevContext; m_prevReadSurf = prevReadSurf; m_prevDrawSurf = prevDrawSurf; @@ -1059,64 +957,37 @@ bool FrameBuffer::unbind_locked() return true; } -bool FrameBuffer::post(HandleType p_colorbuffer, bool needLock) +bool FrameBuffer::post(FrameBufferWindow *window, HandleType p_colorbuffer, bool needLock) { - if (needLock) { + if (!window) + return false; + + printf("%s window %p\n", __func__, window); + + if (needLock) m_lock.lock(); - } - bool ret = false; + + bool ret; ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); - if (c == m_colorbuffers.end()) { + if (c == m_colorbuffers.end()) goto EXIT; - } m_lastPostedColorBuffer = p_colorbuffer; - if (m_subWin) { - // bind the subwindow eglSurface - if (!bindSubwin_locked()) { - ERR("FrameBuffer::post(): eglMakeCurrent failed\n"); - goto EXIT; - } + if (!bindWindow_locked(window)) + goto EXIT; - // get the viewport - GLint vp[4]; - s_gles2.glGetIntegerv(GL_VIEWPORT, vp); - - // divide by device pixel ratio because windowing coordinates ignore DPR, - // but the framebuffer includes DPR - vp[2] = vp[2] / m_dpr; - vp[3] = vp[3] / m_dpr; - - // find the x and y values at the origin when "fully scrolled" - // multiply by 2 because the texture goes from -1 to 1, not 0 to 1 - float fx = 2.f * (vp[2] - m_windowWidth) / (float) vp[2]; - float fy = 2.f * (vp[3] - m_windowHeight) / (float) vp[3]; - - // finally, compute translation values - float dx = m_px * fx; - float dy = m_py * fy; - - // - // render the color buffer to the window - // - if (m_zRot != 0.0f) { - s_gles2.glClear(GL_COLOR_BUFFER_BIT); - } - ret = (*c).second.cb->post(m_zRot, dx, dy); - if (ret) { - s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface); - } + s_gles2.glClear(GL_COLOR_BUFFER_BIT); - // restore previous binding - unbind_locked(); - } else { - // If there is no sub-window, don't display anything, the client will - // rely on m_onPost to get the pixels instead. - ret = true; + ret = (*c).second.cb->post(0.0f, 0, 0); + if (ret) { + s_egl.eglSwapBuffers(m_eglDisplay, window->surface); } + // restore previous binding + unbind_locked(); + // // output FPS statistics // @@ -1131,30 +1002,12 @@ bool FrameBuffer::post(HandleType p_colorbuffer, bool needLock) } } - // - // Send framebuffer (without FPS overlay) to callback - // - if (m_onPost) { - (*c).second.cb->readback(m_fbImage); - m_onPost(m_onPostContext, - m_framebufferWidth, - m_framebufferHeight, - -1, - GL_RGBA, - GL_UNSIGNED_BYTE, - m_fbImage); - } - EXIT: + if (!ret) + printf("post: FAILED\n"); + if (needLock) { m_lock.unlock(); } return ret; } - -bool FrameBuffer::repost() { - if (m_lastPostedColorBuffer) { - return post(m_lastPostedColorBuffer); - } - return false; -} diff --git a/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.h b/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.h index b581a4446e04daf84a949d3c2e5a57963ab6f6d7..a3d419d732b29b3cff0266f2eb196f48354ae5fc 100644 --- a/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.h +++ b/external/android-emugl/host/libs/libOpenglRender/FrameBuffer.h @@ -58,6 +58,8 @@ struct FrameBufferCaps { EGLint eglMinor; }; +struct FrameBufferWindow; + // The FrameBuffer class holds the global state of the emulation library on // top of the underlying EGL/GLES implementation. It should probably be // named "Display" instead of "FrameBuffer". @@ -76,32 +78,8 @@ public: // Returns true on success, false otherwise. static bool initialize(EGLNativeDisplayType nativeDisplay, int width, int height, bool useSubWindow); - // Setup a sub-window to display the content of the emulated GPU - // on-top of an existing UI window. |p_window| is the platform-specific - // parent window handle. |wx|, |wy|, |ww| and |wh| are the - // dimensions in pixels of the sub-window, relative to the parent window's - // coordinate. |fbw| and |fbh| are the dimensions used to initialize - // the framebuffer, which may be different from the dimensions of the - // sub-window (in which case scaling will be applied automatically). - // |dpr| is the device pixel ratio of the monitor, which is needed for - // proper panning on high-density displays (like retina) - // |zRot| is a rotation angle in degrees, (clockwise in the Y-upwards GL - // coordinate space). - // - // If a sub-window already exists, this function updates the subwindow - // and framebuffer properties to match the given values. - // - // Return true on success, false otherwise. - // - // NOTE: This can return false for software-only EGL engines like OSMesa. - bool setupSubWindow(FBNativeWindowType p_window, - int wx, int wy, - int ww, int wh, - int fbw, int fbh, float dpr, float zRot); - - // Remove the sub-window created by setupSubWindow(), if any. - // Return true on success, false otherwise. - bool removeSubWindow(); + FrameBufferWindow* createWindow(int x, int y, int width, int height); + void destroyWindow(FrameBufferWindow *window); // Finalize the instance. void finalize(); @@ -113,12 +91,6 @@ public: // Return the capabilities of the underlying display. const FrameBufferCaps &getCaps() const { return m_caps; } - // Return the emulated GPU display width in pixels. - int getWidth() const { return m_framebufferWidth; } - - // Return the emulated GPU display height in pixels. - int getHeight() const { return m_framebufferHeight; } - // Return the list of configs available from this display. const FbConfigList* getConfigs() const { return m_configs; } @@ -259,36 +231,11 @@ public: // |needLock| is used to indicate whether the operation requires // acquiring/releasing the FrameBuffer instance's lock. It should be // false only when called internally. - bool post(HandleType p_colorbuffer, bool needLock = true); - - // Re-post the last ColorBuffer that was displayed through post(). - // This is useful if you detect that the sub-window content needs to - // be re-displayed for any reason. - bool repost(); + bool post(FrameBufferWindow *window, HandleType p_colorbuffer, bool needLock = true); // Return the host EGLDisplay used by this instance. EGLDisplay getDisplay() const { return m_eglDisplay; } - // Change the rotation of the displayed GPU sub-window. - void setDisplayRotation(float zRot) { - m_zRot = zRot; - repost(); - } - - // Changes what coordinate of this framebuffer will be displayed at the - // corner of the GPU sub-window. Specifically, |px| and |py| = 0 means - // align the bottom-left of the framebuffer with the bottom-left of the - // sub-window, and |px| and |py| = 1 means align the top right of the - // framebuffer with the top right of the sub-window. Intermediate values - // interpolate between these states. - void setDisplayTranslation(float px, float py) { - - // Sanity check the values to ensure they are between 0 and 1 - m_px = px > 1 ? 1 : (px < 0 ? 0 : px); - m_py = py > 1 ? 1 : (py < 0 ? 0 : py); - repost(); - } - // Return a TextureDraw instance that can be used with this surfaces // and windows created by this instance. TextureDraw* getTextureDraw() const { return m_textureDraw; } @@ -305,18 +252,11 @@ private: ~FrameBuffer(); HandleType genHandle(); - bool bindSubwin_locked(); + bool bindWindow_locked(FrameBufferWindow *window); private: static FrameBuffer *s_theFrameBuffer; static HandleType s_nextHandle; - int m_x; - int m_y; - int m_framebufferWidth; - int m_framebufferHeight; - int m_windowWidth; - int m_windowHeight; - float m_dpr; bool m_useSubWindow; emugl::Mutex m_lock; FbConfigList* m_configs; @@ -328,7 +268,6 @@ private: ColorBufferMap m_colorbuffers; ColorBuffer::Helper* m_colorBufferHelper; - EGLSurface m_eglSurface; EGLContext m_eglContext; EGLSurface m_pbufSurface; EGLContext m_pbufContext; @@ -336,23 +275,14 @@ private: EGLContext m_prevContext; EGLSurface m_prevReadSurf; EGLSurface m_prevDrawSurf; - EGLNativeWindowType m_subWin; TextureDraw* m_textureDraw; EGLConfig m_eglConfig; HandleType m_lastPostedColorBuffer; - float m_zRot; - float m_px; - float m_py; - bool m_eglContextInitialized; int m_statsNumFrames; long long m_statsStartTime; bool m_fpsStats; - OnPostFn m_onPost; - void* m_onPostContext; - unsigned char* m_fbImage; - const char* m_glVendor; const char* m_glRenderer; const char* m_glVersion; diff --git a/external/android-emugl/host/libs/libOpenglRender/LayerManager.cpp b/external/android-emugl/host/libs/libOpenglRender/LayerManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a90a455942facbb351e991257d9377fc23dd9bd3 --- /dev/null +++ b/external/android-emugl/host/libs/libOpenglRender/LayerManager.cpp @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#include "LayerManager.h" + +#include + +namespace { +std::string get_package_name(const std::string &name) { + return name; +} + +bool is_layer_blacklisted(const std::string &name) { + static std::vector blacklist = { + "BootAnimation", + "StatusBar", + "Sprite", + "KeyguardScrim", + "com.android.launcher/com.android.launcher2.Launcher", + "com.android.settings/com.android.settings.FallbackHome", + "com.android.systemui.ImageWallpaper", + "InputMethod", + }; + return std::find(blacklist.begin(), blacklist.end(), name) != blacklist.end(); +} +} + +std::shared_ptr LayerManager::get() { + static auto self = std::shared_ptr{new LayerManager}; + return self; +} + +LayerManager::LayerManager() { +} + +LayerManager::~LayerManager() { +} + +void LayerManager::post_layer(const LayerInfo &layer) { + if (is_layer_blacklisted(layer.name)) { + printf("Ignoring blacklisted layer '%s'\n", layer.name.c_str()); + return; + } + + FrameBufferWindow *window = nullptr; + auto l = layers_.find(layer.name); + if (l != layers_.end()) { + printf("Using existing layer '%s'\n", layer.name.c_str()); + window = l->second.window; + l->second.updated = true; + } + else { + printf("New layer '%s' {%d,%d,%d,%d}\n", layer.name.c_str()); + window = FrameBuffer::getFB()->createWindow( + layer.display_frame.left, + layer.display_frame.top, + layer.display_frame.right, + layer.display_frame.bottom); + if (!window) { + printf("Failed to create window for layer '%s'\n", layer.name.c_str()); + return; + } + layers_.insert({ layer.name, Layer{window, true}}); + } + + printf("%s: window %p buffer %d\n", __func__, window, layer.buffer_handle); + + FrameBuffer::getFB()->post(window, layer.buffer_handle); +} + +void LayerManager::finish_cycle() { + for (auto iter = layers_.begin(); iter != layers_.end(); ++iter) { + if (!iter->second.updated) { + FrameBuffer::getFB()->destroyWindow(iter->second.window); + layers_.erase(iter); + } + } +} diff --git a/external/android-emugl/host/libs/libOpenglRender/LayerManager.h b/external/android-emugl/host/libs/libOpenglRender/LayerManager.h new file mode 100644 index 0000000000000000000000000000000000000000..52b91006af1f76c6dce95e290c579dccce34b1f3 --- /dev/null +++ b/external/android-emugl/host/libs/libOpenglRender/LayerManager.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 Simon Fels + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + */ + +#ifndef LAYER_MANAGER_H_ +#define LAYER_MANAGER_H_ + +#include + +#include +#include +#include + +#include "FrameBuffer.h" + +struct LayerRect { + int top; + int left; + 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 get(); + + ~LayerManager(); + + void post_layer(const LayerInfo &layer); + void finish_cycle(); + +private: + LayerManager(); + + struct Layer { + FrameBufferWindow *window; + bool updated; + }; + + std::map layers_; +}; + +#endif diff --git a/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow.h b/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow.h index 49af52b6e2ded3c7ce14d5c13af2fe0ee287b476..21a379c4370e0f52db0530d82eb6d1bf4718ce45 100644 --- a/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow.h +++ b/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow.h @@ -35,8 +35,6 @@ public: void registerSubWindowHandler(const std::shared_ptr &handler); -typedef void (*SubWindowRepaintCallback)(void*); - // 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. @@ -55,25 +53,11 @@ EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, int x, int y, int width, - int height, - SubWindowRepaintCallback repaint_callback, - void* repaint_callback_param); + int height); // Destroy a sub-window previously created through createSubWindow() above. void destroySubWindow(EGLNativeWindowType win); -// Moves a sub-window previously created through createSubWindow() above. -// |p_parent_window| is the platform-specific handle to the main UI window. -// |p_sub_window| is the platform-specific handle to the EGL subwindow. -// |x|,|y|,|width|,|height| are the new location and dimensions of the -// subwindow. -int moveSubWindow(FBNativeWindowType p_parent_window, - EGLNativeWindowType p_sub_window, - int x, - int y, - int width, - int height); - #ifdef __cplusplus } #endif diff --git a/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow_delegate.cpp b/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow_delegate.cpp index 8984d2f1f52c5d02f1eea6db82852d2b214e2f21..1eab521f67133c9f583a8ac7e4b0925f2a8e4d36 100644 --- a/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow_delegate.cpp +++ b/external/android-emugl/host/libs/libOpenglRender/NativeSubWindow_delegate.cpp @@ -35,12 +35,8 @@ EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, int x, int y, int width, - int height, - SubWindowRepaintCallback repaint_callback, - void* repaint_callback_param) { + int height) { (void) p_window; - (void) repaint_callback; - (void) repaint_callback_param; if (!current_handler) return (EGLNativeWindowType) 0; @@ -54,19 +50,3 @@ void destroySubWindow(EGLNativeWindowType win) { return current_handler->destroy_window(win); } - -int moveSubWindow(FBNativeWindowType p_parent_window, - EGLNativeWindowType p_sub_window, - int x, - int y, - int width, - int height) { - (void) p_parent_window; - (void) p_sub_window; - (void) x; - (void) y; - (void) width; - (void) height; - - return true; -} diff --git a/external/android-emugl/host/libs/libOpenglRender/render_api.cpp b/external/android-emugl/host/libs/libOpenglRender/RenderApi.cpp similarity index 76% rename from external/android-emugl/host/libs/libOpenglRender/render_api.cpp rename to external/android-emugl/host/libs/libOpenglRender/RenderApi.cpp index 228119f1b07ab4a48a2b0b4f27fbcb29e07531db..d8b0317b233b6697e796444f9195e6eaa52d42cd 100644 --- a/external/android-emugl/host/libs/libOpenglRender/render_api.cpp +++ b/external/android-emugl/host/libs/libOpenglRender/RenderApi.cpp @@ -21,11 +21,7 @@ #include "TimeUtils.h" #include "TcpStream.h" -#ifdef _WIN32 -#include "Win32PipeStream.h" -#else #include "UnixStream.h" -#endif #include "DispatchTables.h" @@ -142,15 +138,6 @@ RENDER_APICALL int RENDER_APIENTRY initOpenGLRenderer( return true; } -RENDER_APICALL void RENDER_APIENTRY setPostCallback( - OnPostFn onPost, void* onPostContext) { - if (s_renderWindow) { - s_renderWindow->setPostCallback(onPost, onPostContext); - } else { - ERR("Calling setPostCallback() before creating render window!"); - } -} - RENDER_APICALL void RENDER_APIENTRY getHardwareStrings( const char** vendor, const char** renderer, @@ -228,53 +215,7 @@ RENDER_APICALL bool RENDER_APIENTRY destroyOpenGLSubwindow(void) return false; } -RENDER_APICALL void RENDER_APIENTRY setOpenGLDisplayRotation(float zRot) -{ - RenderWindow* window = s_renderWindow; - - if (window) { - window->setRotation(zRot); - return; - } - // XXX: should be implemented by sending the renderer process - // a request - ERR("%s not implemented for separate renderer process !!!\n", - __FUNCTION__); -} - -RENDER_APICALL void RENDER_APIENTRY setOpenGLDisplayTranslation(float px, float py) -{ - RenderWindow* window = s_renderWindow; - - if (window) { - window->setTranslation(px, py); - return; - } - // XXX: should be implemented by sending the renderer process - // a request - ERR("%s not implemented for separate renderer process !!!\n", - __FUNCTION__); -} - -RENDER_APICALL void RENDER_APIENTRY repaintOpenGLDisplay(void) -{ - RenderWindow* window = s_renderWindow; - - if (window) { - window->repaint(); - return; - } - // XXX: should be implemented by sending the renderer process - // a request - ERR("%s not implemented for separate renderer process !!!\n", - __FUNCTION__); -} - - -/* NOTE: For now, always use TCP mode by default, until the emulator - * has been updated to support Unix and Win32 pipes - */ -#define DEFAULT_STREAM_MODE RENDER_API_STREAM_MODE_TCP +#define DEFAULT_STREAM_MODE RENDER_API_STREAM_MODE_UNIX int gRendererStreamMode = DEFAULT_STREAM_MODE; @@ -285,11 +226,7 @@ IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags) if (gRendererStreamMode == RENDER_API_STREAM_MODE_TCP) { stream = new TcpStream(p_stream_buffer_size); } else { -#ifdef _WIN32 - stream = new Win32PipeStream(p_stream_buffer_size); -#else /* !_WIN32 */ stream = new UnixStream(p_stream_buffer_size); -#endif } if (!stream) { @@ -312,28 +249,3 @@ IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags) return stream; } - -RENDER_APICALL int RENDER_APIENTRY setStreamMode(int mode) -{ - switch (mode) { - case RENDER_API_STREAM_MODE_DEFAULT: - mode = DEFAULT_STREAM_MODE; - break; - - case RENDER_API_STREAM_MODE_TCP: - break; - -#ifndef _WIN32 - case RENDER_API_STREAM_MODE_UNIX: - break; -#else /* _WIN32 */ - case RENDER_API_STREAM_MODE_PIPE: - break; -#endif /* _WIN32 */ - default: - // Invalid stream mode - return false; - } - gRendererStreamMode = mode; - return true; -} diff --git a/external/android-emugl/host/libs/libOpenglRender/RenderControl.cpp b/external/android-emugl/host/libs/libOpenglRender/RenderControl.cpp index 44fd1138dc425d87c089823a065bd5e099d2a369..c36769a4a76d9702dd3af36612ca9c04bd3b53c0 100644 --- a/external/android-emugl/host/libs/libOpenglRender/RenderControl.cpp +++ b/external/android-emugl/host/libs/libOpenglRender/RenderControl.cpp @@ -20,9 +20,13 @@ #include "FrameBuffer.h" #include "RenderThreadInfo.h" #include "ChecksumCalculatorThreadInfo.h" +#include "LayerManager.h" #include "OpenGLESDispatch/EGLDispatch.h" +#include +#include + static const GLint rendererVersion = 1; static GLint rcGetRendererVersion() @@ -156,10 +160,12 @@ static EGLint rcGetFBParam(EGLint param) switch(param) { case FB_WIDTH: - ret = fb->getWidth(); + // FIXME DISPLAY MANAGER!! + ret = 1920; break; case FB_HEIGHT: - ret = fb->getHeight(); + // FIXME DISPLAY MANAGER!! + ret = 1080; break; case FB_XDPI: ret = 72; // XXX: should be implemented @@ -306,7 +312,7 @@ static void rcFBPost(uint32_t colorBuffer) return; } - fb->post(colorBuffer); + fb->post(nullptr, colorBuffer); } static void rcFBSetSwapInterval(EGLint interval) @@ -392,6 +398,56 @@ static void rcSelectChecksumCalculator(uint32_t protocol, uint32_t reserved) { ChecksumCalculatorThreadInfo::setVersion(protocol); } +int rcGetNumDisplays() { + return 1; +} + +int rcGetDisplayWidth(uint32_t display_id) { + printf("%s: display_id=%d\n", __func__, display_id); + return 1920; +} + +int rcGetDisplayHeight(uint32_t display_id) { + printf("%s: display_id=%d\n", __func__, display_id); + return 1080; +} + +int rcGetDisplayDpiX(uint32_t display_id) { + printf("%s: display_id=%d\n", __func__, display_id); + return 120; +} + +int rcGetDisplayDpiY(uint32_t display_id) { + printf("%s: display_id=%d\n", __func__, display_id); + return 120; +} + +int rcGetDisplayVsyncPeriod(uint32_t display_id) { + printf("%s: display_id=%d\n", __func__, display_id); + return 1; +} + +void rcPostLayer(const char *name, uint32_t color_buffer, + int32_t sourceCropLeft, int32_t sourceCropTop, + int32_t sourceCropRight, int32_t sourceCropBottom, + int32_t displayFrameLeft, int32_t displayFrameTop, + int32_t displayFrameRight, int32_t displayFrameBottom) { + + printf("%s: name='%s' color_buffer=%d {%d,%d,%d,%d}, {%d,%d,%d,%d}\n", + __func__, name, color_buffer, + sourceCropLeft, sourceCropTop, sourceCropRight, sourceCropBottom, + displayFrameLeft, displayFrameTop, displayFrameRight, 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 initRenderControlContext(renderControl_decoder_context_t *dec) { dec->rcGetRendererVersion = rcGetRendererVersion; @@ -423,4 +479,12 @@ void initRenderControlContext(renderControl_decoder_context_t *dec) dec->rcCreateClientImage = rcCreateClientImage; dec->rcDestroyClientImage = rcDestroyClientImage; dec->rcSelectChecksumCalculator = rcSelectChecksumCalculator; + dec->rcGetNumDisplays = rcGetNumDisplays; + dec->rcGetDisplayWidth = rcGetDisplayWidth; + dec->rcGetDisplayHeight = rcGetDisplayHeight; + dec->rcGetDisplayDpiX = rcGetDisplayDpiX; + dec->rcGetDisplayDpiY = rcGetDisplayDpiY; + dec->rcGetDisplayVsyncPeriod = rcGetDisplayVsyncPeriod; + dec->rcPostLayer = rcPostLayer; + dec->rcPostAllLayersDone = rcPostAllLayersDone; } diff --git a/external/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp b/external/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp index ced43deb9811a92e9883955ec8c325c78f19d640..31f50bd0b2dd56788b37c9cad29c02c15a2b78d4 100644 --- a/external/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp +++ b/external/android-emugl/host/libs/libOpenglRender/RenderWindow.cpp @@ -138,69 +138,6 @@ struct RenderWindowMessage { result = true; break; - case CMD_SET_POST_CALLBACK: - D("CMD_SET_POST_CALLBACK\n"); - fb = FrameBuffer::getFB(); - fb->setPostCallback(msg.set_post_callback.on_post, - msg.set_post_callback.on_post_context); - result = true; - break; - - case CMD_SETUP_SUBWINDOW: - D("CMD_SETUP_SUBWINDOW: parent=%p wx=%d wy=%d ww=%d wh=%d fbw=%d fbh=%d dpr=%f rotation=%f\n", - (void*)msg.subwindow.parent, - msg.subwindow.wx, - msg.subwindow.wy, - msg.subwindow.ww, - msg.subwindow.wh, - msg.subwindow.fbw, - msg.subwindow.fbh, - msg.subwindow.dpr, - msg.subwindow.rotation); - result = FrameBuffer::getFB()->setupSubWindow( - msg.subwindow.parent, - msg.subwindow.wx, - msg.subwindow.wy, - msg.subwindow.ww, - msg.subwindow.wh, - msg.subwindow.fbw, - msg.subwindow.fbh, - msg.subwindow.dpr, - msg.subwindow.rotation); - break; - - case CMD_REMOVE_SUBWINDOW: - D("CMD_REMOVE_SUBWINDOW\n"); - result = FrameBuffer::getFB()->removeSubWindow(); - break; - - case CMD_SET_ROTATION: - D("CMD_SET_ROTATION rotation=%f\n", msg.rotation); - fb = FrameBuffer::getFB(); - if (fb) { - fb->setDisplayRotation(msg.rotation); - result = true; - } - break; - - case CMD_SET_TRANSLATION: - D("CMD_SET_TRANSLATION translation=%f,%f\n", msg.trans.px, msg.trans.py); - fb = FrameBuffer::getFB(); - if (fb) { - fb->setDisplayTranslation(msg.trans.px, msg.trans.py); - result = true; - } - break; - - case CMD_REPAINT: - D("CMD_REPAINT\n"); - fb = FrameBuffer::getFB(); - if (fb) { - fb->repost(); - result = true; - } - break; - default: ; } @@ -370,16 +307,6 @@ bool RenderWindow::getHardwareStrings(const char** vendor, return true; } -void RenderWindow::setPostCallback(OnPostFn onPost, void* onPostContext) { - D("Entering\n"); - RenderWindowMessage msg; - msg.cmd = CMD_SET_POST_CALLBACK; - msg.set_post_callback.on_post = onPost; - msg.set_post_callback.on_post_context = onPostContext; - (void) processMessage(msg); - D("Exiting\n"); -} - bool RenderWindow::setupSubWindow(FBNativeWindowType window, int wx, int wy, diff --git a/external/android-emugl/host/libs/libOpenglRender/RenderWindow.h b/external/android-emugl/host/libs/libOpenglRender/RenderWindow.h index 1443688632a3854859e53b65400c528c5092664f..63894759cdb0930a3cbe2b1e404c23faee08d94d 100644 --- a/external/android-emugl/host/libs/libOpenglRender/RenderWindow.h +++ b/external/android-emugl/host/libs/libOpenglRender/RenderWindow.h @@ -75,11 +75,6 @@ public: const char** renderer, const char** version); - // Specify a function that will be called everytime a new frame is - // displayed. This is relatively slow but allows one to capture the - // output. - void setPostCallback(OnPostFn onPost, void* onPostContext); - // Start displaying the emulated framebuffer using a sub-window of a // parent |window| id. |wx|, |wy|, |ww| and |wh| are the position // and dimension of the sub-window, relative to its parent. diff --git a/external/android-emugl/host/libs/renderControl_dec/renderControl.attrib b/external/android-emugl/host/libs/renderControl_dec/renderControl.attrib index 0afa9d3c57a9580c054b0f1ebbf3485f588fb731..4a3bb1832c08041238bd0ce9bde2fa6cd2b84957 100644 --- a/external/android-emugl/host/libs/renderControl_dec/renderControl.attrib +++ b/external/android-emugl/host/libs/renderControl_dec/renderControl.attrib @@ -42,3 +42,6 @@ rcUpdateColorBuffer rcCloseColorBuffer flag flushOnEncode + +rcPostLayer + len name (strlen(name) + 1) diff --git a/external/android-emugl/host/libs/renderControl_dec/renderControl.in b/external/android-emugl/host/libs/renderControl_dec/renderControl.in index 2cc40316eb2b0eaf70986d5a71e6f224385dd08e..a632a0a173c6d0b14b59a48d52e53c03a4454422 100644 --- a/external/android-emugl/host/libs/renderControl_dec/renderControl.in +++ b/external/android-emugl/host/libs/renderControl_dec/renderControl.in @@ -27,3 +27,11 @@ GL_ENTRY(int, rcOpenColorBuffer2, uint32_t colorbuffer) GL_ENTRY(uint32_t, rcCreateClientImage, uint32_t context, EGLenum target, GLuint buffer) GL_ENTRY(int, rcDestroyClientImage, uint32_t image) GL_ENTRY(void, rcSelectChecksumCalculator, uint32_t newProtocol, uint32_t reserved) +GL_ENTRY(int, rcGetNumDisplays) +GL_ENTRY(int, rcGetDisplayWidth, uint32_t displayId) +GL_ENTRY(int, rcGetDisplayHeight, uint32_t displayId) +GL_ENTRY(int, rcGetDisplayDpiX, uint32_t displayId) +GL_ENTRY(int, rcGetDisplayDpiY, uint32_t displayId) +GL_ENTRY(int, rcGetDisplayVsyncPeriod, uint32_t displayId) +GL_ENTRY(void, rcPostLayer, const char* name, uint32_t colorBuffer, int32_t sourceCropLeft, int32_t sourceCropTop, int32_t sourceCropRight, int32_t sourceCropBottom, int32_t displayFrameLeft, int32_t displayFrameTop, int32_t displayFrameRight, int32_t displayFrameBottom) +GL_ENTRY(void, rcPostAllLayersDone) diff --git a/external/android-emugl/host/libs/renderControl_dec/renderControl.types b/external/android-emugl/host/libs/renderControl_dec/renderControl.types index 2b3847078d24ac0922bfbb87ac87155b6a94310b..9bb0546714cf51f418385442347c5cf77d01d205 100644 --- a/external/android-emugl/host/libs/renderControl_dec/renderControl.types +++ b/external/android-emugl/host/libs/renderControl_dec/renderControl.types @@ -1,4 +1,5 @@ uint32_t 32 0x%08x +int32_t 32 0x%08x EGLint 32 0x%08x GLint 32 0x%08x GLuint 32 0x%08x @@ -9,3 +10,4 @@ EGLint* 32 0x%08x GLint* 32 0x%08x GLuint* 32 0x%08x void* 32 0x%08x +char* 32 0x%08x diff --git a/src/anbox/cmds/run.cpp b/src/anbox/cmds/run.cpp index 7fffe2674f58d195f1676dbd524dabe36a48ed52..674ac9ffd569d1dab583f42dc6fefc6eaa54d355 100644 --- a/src/anbox/cmds/run.cpp +++ b/src/anbox/cmds/run.cpp @@ -140,7 +140,7 @@ anbox::cmds::Run::Run(const BusFactory& bus_factory) // { qemud_connector->socket_file(), "/dev/qemud" }, { qemu_pipe_connector->socket_file(), "/dev/qemu_pipe" }, { bridge_connector->socket_file(), "/dev/anbox_bridge" }, - { config::host_input_device_path(), "/dev/input" }, + { "/dev/input", "/dev/input" }, { "/dev/binder", "/dev/binder" }, { "/dev/ashmem", "/dev/ashmem" }, }; diff --git a/src/anbox/graphics/gl_renderer_server.cpp b/src/anbox/graphics/gl_renderer_server.cpp index 50624f0f0a51f73a2c1d8e7bd8fc3f7c82477449..3b6d3af3c025e3170b8c8d05ccb72f9f100788ef 100644 --- a/src/anbox/graphics/gl_renderer_server.cpp +++ b/src/anbox/graphics/gl_renderer_server.cpp @@ -45,13 +45,11 @@ GLRendererServer::GLRendererServer(const std::shared_ptr &window_ if (!initLibrary()) BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize OpenGL renderer")); - setStreamMode(RENDER_API_STREAM_MODE_UNIX); - registerSubWindowHandler(window_creator_); } GLRendererServer::~GLRendererServer() { - destroyOpenGLSubwindow(); + // destroyOpenGLSubwindow(); stopOpenGLRenderer(); } @@ -84,11 +82,13 @@ void GLRendererServer::start() { socket_path_ = server_addr; +#if 0 // Create the window we use for rendering the output we get from the // Android container. This will internally construct a Mir surface // and use the host EGL/GLES libraries for rendering. if (!showOpenGLSubwindow(0, 0, 0, width, height, width, height, 1.0f, 0)) BOOST_THROW_EXCEPTION(std::runtime_error("Failed to setup GL based window")); +#endif } std::string GLRendererServer::socket_path() const { diff --git a/src/anbox/qemu/boot_properties_message_processor.cpp b/src/anbox/qemu/boot_properties_message_processor.cpp index d5b54c20b61444b03e694376a6bed327eb0b2ae1..a1f930031825c1be947ba040e2cb132c0d8486b3 100644 --- a/src/anbox/qemu/boot_properties_message_processor.cpp +++ b/src/anbox/qemu/boot_properties_message_processor.cpp @@ -54,7 +54,7 @@ void BootPropertiesMessageProcessor::list_properties() { // TODO(morphis): Using HDPI here for now but should be adjusted to the device // we're running on. - utils::string_format("ro.sf.lcd_density=%d", static_cast(graphics::DensityType::high)), + utils::string_format("ro.sf.lcd_density=%d", static_cast(graphics::DensityType::medium)), // Disable on-screen virtual keys as we can use the hardware keyboard "qemu.hw.mainkeys=1", diff --git a/src/anbox/ubuntu/window.cpp b/src/anbox/ubuntu/window.cpp index 8a057bb85f377811c5d6a14ef44abcae3917ea72..f024deeebb08446dc66137a08f74988c963a8d3a 100644 --- a/src/anbox/ubuntu/window.cpp +++ b/src/anbox/ubuntu/window.cpp @@ -16,338 +16,26 @@ */ #include "anbox/ubuntu/window.h" -#include "anbox/input/manager.h" -#include "anbox/input/device.h" #include "anbox/logger.h" #include #include -namespace { -class SlotFingerMapper { -public: - int find_or_create(SDL_FingerID id) { - auto iter = std::find(slots_.begin(), slots_.end(), id); - if (iter != slots_.end()) - return std::distance(slots_.begin(), iter); - - std::vector::size_type i; - for(i = 0;i < slots_.size();i++) { - if (slots_[i] == -1) { - slots_[i] = id; - return i; - } - } - - slots_.resize(slots_.size() + 1); - slots_[slots_.size() - 1] = id; - - return slots_.size() - 1; - } - - void erase(SDL_FingerID id) - { - auto it = std::find(slots_.begin(), slots_.end(), id); - - if (it != slots_.end()) { - auto index = std::distance(slots_.begin(), it); - slots_[index] = -1; - if (index == slots_.size()-1) { - while (slots_[index] == -1) { - slots_.resize(index); - index--; - } - } - } - } - -private: - std::vector slots_; -}; - -const std::array kKeycodes {{ - SDL_SCANCODE_UNKNOWN, /* KEY_RESERVED 0 */ - SDL_SCANCODE_ESCAPE, /* KEY_ESC 1 */ - SDL_SCANCODE_1, /* KEY_1 2 */ - SDL_SCANCODE_2, /* KEY_2 3 */ - SDL_SCANCODE_3, /* KEY_3 4 */ - SDL_SCANCODE_4, /* KEY_4 5 */ - SDL_SCANCODE_5, /* KEY_5 6 */ - SDL_SCANCODE_6, /* KEY_6 7 */ - SDL_SCANCODE_7, /* KEY_7 8 */ - SDL_SCANCODE_8, /* KEY_8 9 */ - SDL_SCANCODE_9, /* KEY_9 10 */ - SDL_SCANCODE_0, /* KEY_0 11 */ - SDL_SCANCODE_MINUS, /* KEY_MINUS 12 */ - SDL_SCANCODE_EQUALS, /* KEY_EQUAL 13 */ - SDL_SCANCODE_BACKSPACE, /* KEY_BACKSPACE 14 */ - SDL_SCANCODE_TAB, /* KEY_TAB 15 */ - SDL_SCANCODE_Q, /* KEY_Q 16 */ - SDL_SCANCODE_W, /* KEY_W 17 */ - SDL_SCANCODE_E, /* KEY_E 18 */ - SDL_SCANCODE_R, /* KEY_R 19 */ - SDL_SCANCODE_T, /* KEY_T 20 */ - SDL_SCANCODE_Y, /* KEY_Y 21 */ - SDL_SCANCODE_U, /* KEY_U 22 */ - SDL_SCANCODE_I, /* KEY_I 23 */ - SDL_SCANCODE_O, /* KEY_O 24 */ - SDL_SCANCODE_P, /* KEY_P 25 */ - SDL_SCANCODE_LEFTBRACKET, /* KEY_LEFTBRACE 26 */ - SDL_SCANCODE_RIGHTBRACKET, /* KEY_RIGHTBRACE 27 */ - SDL_SCANCODE_RETURN, /* KEY_ENTER 28 */ - SDL_SCANCODE_LCTRL, /* KEY_LEFTCTRL 29 */ - SDL_SCANCODE_A, /* KEY_A 30 */ - SDL_SCANCODE_S, /* KEY_S 31 */ - SDL_SCANCODE_D, /* KEY_D 32 */ - SDL_SCANCODE_F, /* KEY_F 33 */ - SDL_SCANCODE_G, /* KEY_G 34 */ - SDL_SCANCODE_H, /* KEY_H 35 */ - SDL_SCANCODE_J, /* KEY_J 36 */ - SDL_SCANCODE_K, /* KEY_K 37 */ - SDL_SCANCODE_L, /* KEY_L 38 */ - SDL_SCANCODE_SEMICOLON, /* KEY_SEMICOLON 39 */ - SDL_SCANCODE_APOSTROPHE, /* KEY_APOSTROPHE 40 */ - SDL_SCANCODE_GRAVE, /* KEY_GRAVE 41 */ - SDL_SCANCODE_LSHIFT, /* KEY_LEFTSHIFT 42 */ - SDL_SCANCODE_BACKSLASH, /* KEY_BACKSLASH 43 */ - SDL_SCANCODE_Z, /* KEY_Z 44 */ - SDL_SCANCODE_X, /* KEY_X 45 */ - SDL_SCANCODE_C, /* KEY_C 46 */ - SDL_SCANCODE_V, /* KEY_V 47 */ - SDL_SCANCODE_B, /* KEY_B 48 */ - SDL_SCANCODE_N, /* KEY_N 49 */ - SDL_SCANCODE_M, /* KEY_M 50 */ - SDL_SCANCODE_COMMA, /* KEY_COMMA 51 */ - SDL_SCANCODE_PERIOD, /* KEY_DOT 52 */ - SDL_SCANCODE_SLASH, /* KEY_SLASH 53 */ - SDL_SCANCODE_RSHIFT, /* KEY_RIGHTSHIFT 54 */ - SDL_SCANCODE_KP_MULTIPLY, /* KEY_KPASTERISK 55 */ - SDL_SCANCODE_LALT, /* KEY_LEFTALT 56 */ - SDL_SCANCODE_SPACE, /* KEY_SPACE 57 */ - SDL_SCANCODE_CAPSLOCK, /* KEY_CAPSLOCK 58 */ - SDL_SCANCODE_F1, /* KEY_F1 59 */ - SDL_SCANCODE_F2, /* KEY_F2 60 */ - SDL_SCANCODE_F3, /* KEY_F3 61 */ - SDL_SCANCODE_F4, /* KEY_F4 62 */ - SDL_SCANCODE_F5, /* KEY_F5 63 */ - SDL_SCANCODE_F6, /* KEY_F6 64 */ - SDL_SCANCODE_F7, /* KEY_F7 65 */ - SDL_SCANCODE_F8, /* KEY_F8 66 */ - SDL_SCANCODE_F9, /* KEY_F9 67 */ - SDL_SCANCODE_F10, /* KEY_F10 68 */ - SDL_SCANCODE_NUMLOCKCLEAR, /* KEY_NUMLOCK 69 */ - SDL_SCANCODE_SCROLLLOCK, /* KEY_SCROLLLOCK 70 */ - SDL_SCANCODE_KP_7, /* KEY_KP7 71 */ - SDL_SCANCODE_KP_8, /* KEY_KP8 72 */ - SDL_SCANCODE_KP_9, /* KEY_KP9 73 */ - SDL_SCANCODE_KP_MINUS, /* KEY_KPMINUS 74 */ - SDL_SCANCODE_KP_4, /* KEY_KP4 75 */ - SDL_SCANCODE_KP_5, /* KEY_KP5 76 */ - SDL_SCANCODE_KP_6, /* KEY_KP6 77 */ - SDL_SCANCODE_KP_PLUS, /* KEY_KPPLUS 78 */ - SDL_SCANCODE_KP_1, /* KEY_KP1 79 */ - SDL_SCANCODE_KP_2, /* KEY_KP2 80 */ - SDL_SCANCODE_KP_3, /* KEY_KP3 81 */ - SDL_SCANCODE_KP_0, /* KEY_KP0 82 */ - SDL_SCANCODE_KP_PERIOD, /* KEY_KPDOT 83 */ - SDL_SCANCODE_UNKNOWN, /* 84 */ - SDL_SCANCODE_LANG5, /* KEY_ZENKAKUHANKAKU 85 */ - SDL_SCANCODE_UNKNOWN, /* KEY_102ND 86 */ - SDL_SCANCODE_F11, /* KEY_F11 87 */ - SDL_SCANCODE_F12, /* KEY_F12 88 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RO 89 */ - SDL_SCANCODE_LANG3, /* KEY_KATAKANA 90 */ - SDL_SCANCODE_LANG4, /* KEY_HIRAGANA 91 */ - SDL_SCANCODE_UNKNOWN, /* KEY_HENKAN 92 */ - SDL_SCANCODE_LANG3, /* KEY_KATAKANAHIRAGANA 93 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MUHENKAN 94 */ - SDL_SCANCODE_KP_COMMA, /* KEY_KPJPCOMMA 95 */ - SDL_SCANCODE_KP_ENTER, /* KEY_KPENTER 96 */ - SDL_SCANCODE_RCTRL, /* KEY_RIGHTCTRL 97 */ - SDL_SCANCODE_KP_DIVIDE, /* KEY_KPSLASH 98 */ - SDL_SCANCODE_SYSREQ, /* KEY_SYSRQ 99 */ - SDL_SCANCODE_RALT, /* KEY_RIGHTALT 100 */ - SDL_SCANCODE_UNKNOWN, /* KEY_LINEFEED 101 */ - SDL_SCANCODE_HOME, /* KEY_HOME 102 */ - SDL_SCANCODE_UP, /* KEY_UP 103 */ - SDL_SCANCODE_PAGEUP, /* KEY_PAGEUP 104 */ - SDL_SCANCODE_LEFT, /* KEY_LEFT 105 */ - SDL_SCANCODE_RIGHT, /* KEY_RIGHT 106 */ - SDL_SCANCODE_END, /* KEY_END 107 */ - SDL_SCANCODE_DOWN, /* KEY_DOWN 108 */ - SDL_SCANCODE_PAGEDOWN, /* KEY_PAGEDOWN 109 */ - SDL_SCANCODE_INSERT, /* KEY_INSERT 110 */ - SDL_SCANCODE_DELETE, /* KEY_DELETE 111 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MACRO 112 */ - SDL_SCANCODE_MUTE, /* KEY_MUTE 113 */ - SDL_SCANCODE_VOLUMEDOWN, /* KEY_VOLUMEDOWN 114 */ - SDL_SCANCODE_VOLUMEUP, /* KEY_VOLUMEUP 115 */ - SDL_SCANCODE_POWER, /* KEY_POWER 116 SC System Power Down */ - SDL_SCANCODE_KP_EQUALS, /* KEY_KPEQUAL 117 */ - SDL_SCANCODE_KP_MINUS, /* KEY_KPPLUSMINUS 118 */ - SDL_SCANCODE_PAUSE, /* KEY_PAUSE 119 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCALE 120 AL Compiz Scale (Expose) */ - SDL_SCANCODE_KP_COMMA, /* KEY_KPCOMMA 121 */ - SDL_SCANCODE_LANG1, /* KEY_HANGEUL,KEY_HANGUEL 122 */ - SDL_SCANCODE_LANG2, /* KEY_HANJA 123 */ - SDL_SCANCODE_INTERNATIONAL3,/* KEY_YEN 124 */ - SDL_SCANCODE_LGUI, /* KEY_LEFTMETA 125 */ - SDL_SCANCODE_RGUI, /* KEY_RIGHTMETA 126 */ - SDL_SCANCODE_APPLICATION, /* KEY_COMPOSE 127 */ - SDL_SCANCODE_STOP, /* KEY_STOP 128 AC Stop */ - SDL_SCANCODE_AGAIN, /* KEY_AGAIN 129 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PROPS 130 AC Properties */ - SDL_SCANCODE_UNDO, /* KEY_UNDO 131 AC Undo */ - SDL_SCANCODE_UNKNOWN, /* KEY_FRONT 132 */ - SDL_SCANCODE_COPY, /* KEY_COPY 133 AC Copy */ - SDL_SCANCODE_UNKNOWN, /* KEY_OPEN 134 AC Open */ - SDL_SCANCODE_PASTE, /* KEY_PASTE 135 AC Paste */ - SDL_SCANCODE_FIND, /* KEY_FIND 136 AC Search */ - SDL_SCANCODE_CUT, /* KEY_CUT 137 AC Cut */ - SDL_SCANCODE_HELP, /* KEY_HELP 138 AL Integrated Help Center */ - SDL_SCANCODE_MENU, /* KEY_MENU 139 Menu (show menu) */ - SDL_SCANCODE_CALCULATOR, /* KEY_CALC 140 AL Calculator */ - SDL_SCANCODE_UNKNOWN, /* KEY_SETUP 141 */ - SDL_SCANCODE_SLEEP, /* KEY_SLEEP 142 SC System Sleep */ - SDL_SCANCODE_UNKNOWN, /* KEY_WAKEUP 143 System Wake Up */ - SDL_SCANCODE_UNKNOWN, /* KEY_FILE 144 AL Local Machine Browser */ - SDL_SCANCODE_UNKNOWN, /* KEY_SENDFILE 145 */ - SDL_SCANCODE_UNKNOWN, /* KEY_DELETEFILE 146 */ - SDL_SCANCODE_UNKNOWN, /* KEY_XFER 147 */ - SDL_SCANCODE_APP1, /* KEY_PROG1 148 */ - SDL_SCANCODE_APP1, /* KEY_PROG2 149 */ - SDL_SCANCODE_WWW, /* KEY_WWW 150 AL Internet Browser */ - SDL_SCANCODE_UNKNOWN, /* KEY_MSDOS 151 */ - SDL_SCANCODE_UNKNOWN, /* KEY_COFFEE,KEY_SCREENLOCK 152 AL Terminal Lock/Screensaver */ - SDL_SCANCODE_UNKNOWN, /* KEY_DIRECTION 153 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CYCLEWINDOWS 154 */ - SDL_SCANCODE_MAIL, /* KEY_MAIL 155 */ - SDL_SCANCODE_AC_BOOKMARKS, /* KEY_BOOKMARKS 156 AC Bookmarks */ - SDL_SCANCODE_COMPUTER, /* KEY_COMPUTER 157 */ - SDL_SCANCODE_AC_BACK, /* KEY_BACK 158 AC Back */ - SDL_SCANCODE_AC_FORWARD, /* KEY_FORWARD 159 AC Forward */ - SDL_SCANCODE_UNKNOWN, /* KEY_CLOSECD 160 */ - SDL_SCANCODE_EJECT, /* KEY_EJECTCD 161 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EJECTCLOSECD 162 */ - SDL_SCANCODE_AUDIONEXT, /* KEY_NEXTSONG 163 */ - SDL_SCANCODE_AUDIOPLAY, /* KEY_PLAYPAUSE 164 */ - SDL_SCANCODE_AUDIOPREV, /* KEY_PREVIOUSSONG 165 */ - SDL_SCANCODE_AUDIOSTOP, /* KEY_STOPCD 166 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RECORD 167 */ - SDL_SCANCODE_UNKNOWN, /* KEY_REWIND 168 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PHONE 169 Media Select Telephone */ - SDL_SCANCODE_UNKNOWN, /* KEY_ISO 170 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CONFIG 171 AL Consumer Control Configuration */ - SDL_SCANCODE_AC_HOME, /* KEY_HOMEPAGE 172 AC Home */ - SDL_SCANCODE_AC_REFRESH, /* KEY_REFRESH 173 AC Refresh */ - SDL_SCANCODE_UNKNOWN, /* KEY_EXIT 174 AC Exit */ - SDL_SCANCODE_UNKNOWN, /* KEY_MOVE 175 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EDIT 176 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLUP 177 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SCROLLDOWN 178 */ - SDL_SCANCODE_KP_LEFTPAREN, /* KEY_KPLEFTPAREN 179 */ - SDL_SCANCODE_KP_RIGHTPAREN, /* KEY_KPRIGHTPAREN 180 */ - SDL_SCANCODE_UNKNOWN, /* KEY_NEW 181 AC New */ - SDL_SCANCODE_AGAIN, /* KEY_REDO 182 AC Redo/Repeat */ - SDL_SCANCODE_F13, /* KEY_F13 183 */ - SDL_SCANCODE_F14, /* KEY_F14 184 */ - SDL_SCANCODE_F15, /* KEY_F15 185 */ - SDL_SCANCODE_F16, /* KEY_F16 186 */ - SDL_SCANCODE_F17, /* KEY_F17 187 */ - SDL_SCANCODE_F18, /* KEY_F18 188 */ - SDL_SCANCODE_F19, /* KEY_F19 189 */ - SDL_SCANCODE_F20, /* KEY_F20 190 */ - SDL_SCANCODE_F21, /* KEY_F21 191 */ - SDL_SCANCODE_F22, /* KEY_F22 192 */ - SDL_SCANCODE_F23, /* KEY_F23 193 */ - SDL_SCANCODE_F24, /* KEY_F24 194 */ - SDL_SCANCODE_UNKNOWN, /* 195 */ - SDL_SCANCODE_UNKNOWN, /* 196 */ - SDL_SCANCODE_UNKNOWN, /* 197 */ - SDL_SCANCODE_UNKNOWN, /* 198 */ - SDL_SCANCODE_UNKNOWN, /* 199 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PLAYCD 200 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PAUSECD 201 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PROG3 202 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PROG4 203 */ - SDL_SCANCODE_UNKNOWN, /* KEY_DASHBOARD 204 AL Dashboard */ - SDL_SCANCODE_UNKNOWN, /* KEY_SUSPEND 205 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CLOSE 206 AC Close */ - SDL_SCANCODE_UNKNOWN, /* KEY_PLAY 207 */ - SDL_SCANCODE_UNKNOWN, /* KEY_FASTFORWARD 208 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BASSBOOST 209 */ - SDL_SCANCODE_UNKNOWN, /* KEY_PRINT 210 AC Print */ - SDL_SCANCODE_UNKNOWN, /* KEY_HP 211 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CAMERA 212 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SOUND 213 */ - SDL_SCANCODE_UNKNOWN, /* KEY_QUESTION 214 */ - SDL_SCANCODE_UNKNOWN, /* KEY_EMAIL 215 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CHAT 216 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SEARCH 217 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CONNECT 218 */ - SDL_SCANCODE_UNKNOWN, /* KEY_FINANCE 219 AL Checkbook/Finance */ - SDL_SCANCODE_UNKNOWN, /* KEY_SPORT 220 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SHOP 221 */ - SDL_SCANCODE_UNKNOWN, /* KEY_ALTERASE 222 */ - SDL_SCANCODE_UNKNOWN, /* KEY_CANCEL 223 AC Cancel */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSDOWN 224 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESSUP 225 */ - SDL_SCANCODE_UNKNOWN, /* KEY_MEDIA 226 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SWITCHVIDEOMODE 227 Cycle between available video outputs (Monitor/LCD/TV-out/etc) */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMTOGGLE 228 */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMDOWN 229 */ - SDL_SCANCODE_UNKNOWN, /* KEY_KBDILLUMUP 230 */ - SDL_SCANCODE_UNKNOWN, /* KEY_SEND 231 AC Send */ - SDL_SCANCODE_UNKNOWN, /* KEY_REPLY 232 AC Reply */ - SDL_SCANCODE_UNKNOWN, /* KEY_FORWARDMAIL 233 AC Forward Msg */ - SDL_SCANCODE_UNKNOWN, /* KEY_SAVE 234 AC Save */ - SDL_SCANCODE_UNKNOWN, /* KEY_DOCUMENTS 235 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BATTERY 236 */ - SDL_SCANCODE_UNKNOWN, /* KEY_BLUETOOTH 237 */ - SDL_SCANCODE_UNKNOWN, /* KEY_WLAN 238 */ - SDL_SCANCODE_UNKNOWN, /* KEY_UWB 239 */ - SDL_SCANCODE_UNKNOWN, /* KEY_UNKNOWN 240 */ - SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_NEXT 241 drive next video source */ - SDL_SCANCODE_UNKNOWN, /* KEY_VIDEO_PREV 242 drive previous video source */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_CYCLE 243 brightness up, after max is min */ - SDL_SCANCODE_UNKNOWN, /* KEY_BRIGHTNESS_ZERO 244 brightness off, use ambient */ - SDL_SCANCODE_UNKNOWN, /* KEY_DISPLAY_OFF 245 display device to off state */ - SDL_SCANCODE_UNKNOWN, /* KEY_WIMAX 246 */ - SDL_SCANCODE_UNKNOWN, /* KEY_RFKILL 247 Key that controls all radios */ - SDL_SCANCODE_UNKNOWN /* KEY_MICMUTE 248 Mute / unmute the microphone */ -}}; - -std::uint16_t convert_sdl_scancode_to_evdev(const SDL_Scancode &scan_code) { - for (std::uint16_t n = 0; n < kKeycodes.size(); n++) { - if (kKeycodes[n] == scan_code) - return n; - } - return KEY_RESERVED; -} -} - namespace anbox { namespace ubuntu { -Window::Window(const std::shared_ptr &input_manager, - int width, int height) : +Window::Window(int x, int y, int width, int height) : native_display_(0), native_window_(0) { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); - window_ = SDL_CreateWindow("anbox", - SDL_WINDOWPOS_UNDEFINED, - SDL_WINDOWPOS_UNDEFINED, - width, - height, - SDL_WINDOW_OPENGL); + window_ = SDL_CreateWindow("anbox", x, y, width, height, SDL_WINDOW_OPENGL); 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); @@ -363,132 +51,15 @@ Window::Window(const std::shared_ptr &input_manager, } int actual_width = 0, actual_height = 0; + int actual_x = 0, actual_y = 0; SDL_GetWindowSize(window_, &actual_width, &actual_height); - - DEBUG("Window created with %d x %d", actual_width, actual_height); - - // Create our touch panel input device - touchpanel_ = input_manager->create_device(); - touchpanel_->set_name("anbox-touchpanel"); - touchpanel_->set_driver_version(1); - touchpanel_->set_input_id({ BUS_VIRTUAL, 1, 1, 1 }); - touchpanel_->set_physical_location("none"); - touchpanel_->set_abs_bit(ABS_MT_TRACKING_ID); - touchpanel_->set_abs_bit(ABS_MT_SLOT); - touchpanel_->set_abs_bit(ABS_MT_POSITION_X); - touchpanel_->set_abs_bit(ABS_MT_POSITION_Y); - touchpanel_->set_prop_bit(INPUT_PROP_DIRECT); - touchpanel_->set_abs_min(ABS_MT_POSITION_X, 0); - touchpanel_->set_abs_max(ABS_MT_POSITION_X, static_cast(actual_width)); - touchpanel_->set_abs_min(ABS_MT_POSITION_Y, 0); - touchpanel_->set_abs_max(ABS_MT_POSITION_Y, static_cast(actual_height)); - touchpanel_->set_abs_max(ABS_MT_SLOT, 10); - touchpanel_->set_abs_max(ABS_MT_TRACKING_ID, 255); - - pointer_ = input_manager->create_device(); - pointer_->set_name("anbox-pointer"); - pointer_->set_driver_version(1); - pointer_->set_input_id({ BUS_VIRTUAL, 2, 2, 2 }); - pointer_->set_physical_location("none"); - pointer_->set_key_bit(BTN_MOUSE); - // NOTE: We don't use REL_X/REL_Y in reality but have to specify them here - // to allow InputFlinger to detect we're a cursor device. - pointer_->set_rel_bit(REL_X); - pointer_->set_rel_bit(REL_Y); - pointer_->set_rel_bit(REL_HWHEEL); - pointer_->set_rel_bit(REL_WHEEL); - pointer_->set_prop_bit(INPUT_PROP_POINTER); - - keyboard_ = input_manager->create_device(); - keyboard_->set_name("anbox-keyboard"); - keyboard_->set_driver_version(1); - keyboard_->set_input_id({ BUS_VIRTUAL, 3, 3, 3 }); - keyboard_->set_physical_location("none"); - keyboard_->set_key_bit(BTN_MISC); - keyboard_->set_key_bit(KEY_OK); + SDL_GetWindowPosition(window_, &actual_x, &actual_y); + DEBUG("Window created {%d,%d,%d,%d}", actual_x, actual_y, actual_width, actual_height); } Window::~Window() { -} - -void Window::process_input_event(const SDL_Event &event) { - static SlotFingerMapper mapper; - std::vector touch_events; - std::vector mouse_events; - std::vector keyboard_events; - - const auto id = event.tfinger.fingerId; - const auto slot = mapper.find_or_create(id); - - switch (event.type) { - case SDL_FINGERUP: - touch_events.push_back({ EV_ABS, ABS_MT_SLOT, slot }); - touch_events.push_back({ EV_ABS, ABS_MT_TRACKING_ID, -1 }); - touch_events.push_back({ EV_KEY, BTN_TOUCH, 0 }); - touch_events.push_back({ EV_KEY, BTN_TOOL_FINGER, 0 }); - touch_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - mapper.erase(id); - break; - case SDL_FINGERDOWN: - touch_events.push_back({ EV_ABS, ABS_MT_SLOT, slot }); - touch_events.push_back({ EV_ABS, ABS_MT_TRACKING_ID, static_cast(id) }); - touch_events.push_back({ EV_ABS, ABS_MT_POSITION_X, static_cast(event.tfinger.x) }); - touch_events.push_back({ EV_ABS, ABS_MT_POSITION_Y, static_cast(event.tfinger.y) }); - touch_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; - case SDL_FINGERMOTION: - touch_events.push_back({ EV_ABS, ABS_MT_SLOT, slot }); - touch_events.push_back({ EV_ABS, ABS_MT_TRACKING_ID, static_cast(id) }); - touch_events.push_back({ EV_KEY, BTN_TOUCH, 1 }); - touch_events.push_back({ EV_KEY, BTN_TOOL_FINGER, 1 }); - touch_events.push_back({ EV_ABS, ABS_MT_POSITION_X, static_cast(event.tfinger.x) }); - touch_events.push_back({ EV_ABS, ABS_MT_POSITION_Y, static_cast(event.tfinger.y) }); - touch_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; - case SDL_MOUSEBUTTONDOWN: - mouse_events.push_back({ EV_KEY, BTN_LEFT, 1 }); - mouse_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; - case SDL_MOUSEBUTTONUP: - mouse_events.push_back({ EV_KEY, BTN_LEFT, 0 }); - mouse_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; - case SDL_MOUSEMOTION: - // NOTE: Sending relative move events doesn't really work and we have changes - // in libinputflinger to take ABS_X/ABS_Y instead for absolute position events. - mouse_events.push_back({ EV_ABS, ABS_X, static_cast(event.motion.x) }); - mouse_events.push_back({ EV_ABS, ABS_Y, static_cast(event.motion.y) }); - mouse_events.push_back({ EV_SYN, SYN_REPORT, 0 }); - break; - case SDL_MOUSEWHEEL: - mouse_events.push_back({ EV_REL, REL_WHEEL, static_cast(event.wheel.y) }); - break; - case SDL_KEYDOWN: { - const auto code = convert_sdl_scancode_to_evdev(event.key.keysym.scancode); - if (code == KEY_RESERVED) - break; - keyboard_events.push_back({ EV_KEY, code, 1 }); - break; - } - case SDL_KEYUP: { - const auto code = convert_sdl_scancode_to_evdev(event.key.keysym.scancode); - if (code == KEY_RESERVED) - break; - keyboard_events.push_back({ EV_KEY, code, 0 }); - break; - } - default: - break; - } - - if (touch_events.size() > 0) - touchpanel_->send_events(touch_events); - - if (mouse_events.size() > 0) - pointer_->send_events(mouse_events); - - if (keyboard_events.size() > 0) - keyboard_->send_events(keyboard_events); + if (window_) + SDL_DestroyWindow(window_); } EGLNativeWindowType Window::native_window() const { diff --git a/src/anbox/ubuntu/window.h b/src/anbox/ubuntu/window.h index 64782e77d0c0af3758d6be6f8ec7d063b4c91bf1..7911082631a3268632e5e3a6c1096561e61f9174 100644 --- a/src/anbox/ubuntu/window.h +++ b/src/anbox/ubuntu/window.h @@ -26,26 +26,15 @@ #include namespace anbox { -namespace input { -class Manager; -class Device; -class Event; -} // namespace input namespace ubuntu { class Window { public: - Window(const std::shared_ptr &input_manager, - int width, int height); + Window(int x, int y, int width, int height); ~Window(); - void process_input_event(const SDL_Event &event); - EGLNativeWindowType native_window() const; private: - std::shared_ptr touchpanel_; - std::shared_ptr pointer_; - std::shared_ptr keyboard_; EGLNativeDisplayType native_display_; EGLNativeWindowType native_window_; SDL_Window *window_; diff --git a/src/anbox/ubuntu/window_creator.cpp b/src/anbox/ubuntu/window_creator.cpp index 6e05691960ac32e713fd4a3c0100dc0d1e253f80..09d37f3e82ddc54de9026abb813cc7419e177066 100644 --- a/src/anbox/ubuntu/window_creator.cpp +++ b/src/anbox/ubuntu/window_creator.cpp @@ -17,6 +17,8 @@ #include "anbox/ubuntu/window_creator.h" #include "anbox/ubuntu/window.h" +#include "anbox/input/manager.h" +#include "anbox/input/device.h" #include "anbox/logger.h" #include @@ -35,6 +37,16 @@ WindowCreator::WindowCreator(const std::shared_ptr &input_manage if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS) < 0) BOOST_THROW_EXCEPTION(std::runtime_error("Failed to initialize SDL")); +#if 0 + SDL_DisplayMode display_mode; + // FIXME statically just check the first (primary) display for its mode; + // once we get multi-monitor support we need to do this better. + if (SDL_GetCurrentDisplayMode(0, &display_mode) == 0) { + display_info_.horizontal_resolution = display_mode.w; + display_info_.vertical_resolution = display_mode.h; + } +#endif + event_thread_ = std::thread(&WindowCreator::process_events, this); SDL_DisplayMode display_mode; @@ -69,18 +81,6 @@ void WindowCreator::process_events() { case SDL_WINDOWEVENT: process_window_event(event); break; - case SDL_FINGERUP: - case SDL_FINGERMOTION: - case SDL_FINGERDOWN: - case SDL_MOUSEMOTION: - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - case SDL_MOUSEWHEEL: - case SDL_KEYDOWN: - case SDL_KEYUP: - if (current_window_) - current_window_->process_input_event(event); - break; } } } @@ -88,17 +88,11 @@ void WindowCreator::process_events() { EGLNativeWindowType WindowCreator::create_window(int x, int y, int width, int height) try { - if (windows_.size() == 1) { - WARNING("Tried to create another window but we currently only allow one"); - return 0; - } - - auto window = std::make_shared(input_manager_, width, height); + auto window = std::make_shared(x, y, width, height); if (not window) BOOST_THROW_EXCEPTION(std::bad_alloc()); windows_.insert({window->native_window(), window}); - current_window_ = window; return window->native_window(); } diff --git a/src/anbox/ubuntu/window_creator.h b/src/anbox/ubuntu/window_creator.h index cef70c41c8c251f759c34d17db2600a89232ebba..b8e827ec93478cf2cd70bf5130c2262372597344 100644 --- a/src/anbox/ubuntu/window_creator.h +++ b/src/anbox/ubuntu/window_creator.h @@ -27,6 +27,9 @@ #include namespace anbox { +namespace input { +class Device; +} // namespace input namespace ubuntu { class MirDisplayConnection; class Window;