-
Notifications
You must be signed in to change notification settings - Fork 36
wayland-hwc: Drop dummy window hack & QtMir integration improvements #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: lineage-17.1
Are you sure you want to change the base?
Changes from all commits
b91bf2a
d8c6048
8eaef95
1a035ff
41421bd
69e392d
ef1cb3c
bedfe08
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -533,26 +533,33 @@ static int hwc_set(struct hwc_composer_device_1* dev,size_t numDisplays, | |
continue; | ||
} | ||
|
||
const hwc_rect_t frame = fb_layer->displayFrame; | ||
const int width = frame.right - frame.left; | ||
const int height = frame.bottom - frame.top; | ||
|
||
struct window *window = NULL; | ||
std::string layer_name = pdev->display->layer_names[layer]; | ||
|
||
if (active_apps == "Waydroid") { | ||
// Show everything in a single window | ||
if (pdev->windows.find(active_apps) == pdev->windows.end()) { | ||
pdev->windows[active_apps] = create_window(pdev->display, pdev->use_subsurface, active_apps, "0"); | ||
pdev->windows[active_apps] = create_window(pdev->display, pdev->use_subsurface, active_apps, "0", width, height); | ||
property_set("waydroid.open_windows", std::to_string(pdev->windows.size()).c_str()); | ||
} | ||
window = pdev->windows[active_apps]; | ||
} else if (!pdev->use_subsurface) { | ||
if (single_layer_tid.length()) { | ||
if (pdev->windows.find(single_layer_tid) == pdev->windows.end()) { | ||
pdev->windows[single_layer_tid] = create_window(pdev->display, pdev->use_subsurface, single_layer_aid, single_layer_tid); | ||
pdev->windows[single_layer_tid] = create_window(pdev->display, pdev->use_subsurface, single_layer_aid, single_layer_tid, width, height); | ||
property_set("waydroid.open_windows", std::to_string(pdev->windows.size()).c_str()); | ||
} | ||
window = pdev->windows[single_layer_tid]; | ||
|
||
// Window is closed, don't bother | ||
if (!window->isActive) | ||
if (window && !window->isActive) { | ||
free(window); | ||
window = NULL; | ||
} | ||
} | ||
} else { | ||
// Create windows based on Task ID in layer name | ||
|
@@ -573,12 +580,18 @@ static int hwc_set(struct hwc_composer_device_1* dev,size_t numDisplays, | |
|
||
if (showWindow) { | ||
if (pdev->windows.find(layer_tid) == pdev->windows.end()) { | ||
pdev->windows[layer_tid] = create_window(pdev->display, pdev->use_subsurface, layer_aid, layer_tid); | ||
pdev->windows[layer_tid] = create_window(pdev->display, pdev->use_subsurface, layer_aid, layer_tid, width, height); | ||
property_set("waydroid.open_windows", std::to_string(pdev->windows.size()).c_str()); | ||
} | ||
if (pdev->windows.find(layer_tid) != pdev->windows.end()) | ||
window = pdev->windows[layer_tid]; | ||
} | ||
|
||
// Window is closed, don't bother | ||
if (window && !window->isActive) { | ||
free(window); | ||
window = NULL; | ||
} | ||
} | ||
} | ||
|
||
|
@@ -628,7 +641,7 @@ static int hwc_set(struct hwc_composer_device_1* dev,size_t numDisplays, | |
} | ||
if (LayerRawName == "InputMethod") { | ||
if (pdev->windows.find(LayerRawName) == pdev->windows.end()) { | ||
pdev->windows[LayerRawName] = create_window(pdev->display, pdev->use_subsurface, LayerRawName, "none"); | ||
pdev->windows[LayerRawName] = create_window(pdev->display, pdev->use_subsurface, LayerRawName, "none", width, height); | ||
property_set("waydroid.open_windows", std::to_string(pdev->windows.size()).c_str()); | ||
} | ||
if (pdev->windows.find(LayerRawName) != pdev->windows.end()) | ||
|
@@ -1002,6 +1015,9 @@ static int hwc_open(const struct hw_module_t* module, const char* name, | |
if (!property_get_bool("persist.waydroid.cursor_on_subsurface", false)) | ||
pdev->display->cursor_surface = | ||
wl_compositor_create_surface(pdev->display->compositor); | ||
else | ||
pdev->display->cursor_surface = nullptr; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not really well-versed in C++, but since the display is allocated with |
||
|
||
if (!pdev->display->height) { | ||
pdev->display->waiting_for_data = true; | ||
pthread_cond_timedwait(&pdev->display->data_available_cond, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright © 2011 Benjamin Franzke | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a | ||
* copy of this software and associated documentation files (the "Software"), | ||
* to deal in the Software without restriction, including without limitation | ||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
* and/or sell copies of the Software, and to permit persons to whom the | ||
* Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice (including the next | ||
* paragraph) shall be included in all copies or substantial portions of the | ||
* Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
* DEALINGS IN THE SOFTWARE. | ||
* | ||
* Authors: | ||
* Benjamin Franzke <[email protected]> | ||
*/ | ||
|
||
#ifndef _WAYLAND_EGL_PRIV_H | ||
#define _WAYLAND_EGL_PRIV_H | ||
|
||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/* | ||
* NOTE: This version must be kept in sync with the version field in the | ||
* wayland-egl-backend pkgconfig file generated in meson.build. | ||
*/ | ||
#define WL_EGL_WINDOW_VERSION 3 | ||
|
||
struct wl_surface; | ||
|
||
struct wl_egl_window { | ||
const intptr_t version; | ||
|
||
int width; | ||
int height; | ||
int dx; | ||
int dy; | ||
|
||
int attached_width; | ||
int attached_height; | ||
|
||
void *driver_private; | ||
void (*resize_callback)(struct wl_egl_window *, void *); | ||
void (*destroy_window_callback)(void *); | ||
|
||
struct wl_surface *surface; | ||
}; | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/* | ||
* Copyright © 2011 Kristian Høgsberg | ||
* Copyright © 2011 Benjamin Franzke | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a | ||
* copy of this software and associated documentation files (the "Software"), | ||
* to deal in the Software without restriction, including without limitation | ||
* the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
* and/or sell copies of the Software, and to permit persons to whom the | ||
* Software is furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice (including the next | ||
* paragraph) shall be included in all copies or substantial portions of the | ||
* Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
* DEALINGS IN THE SOFTWARE. | ||
* | ||
* Authors: | ||
* Kristian Høgsberg <[email protected]> | ||
* Benjamin Franzke <[email protected]> | ||
*/ | ||
|
||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include "wayland-egl.h" | ||
#include "wayland-egl-backend.h" | ||
#include "wayland-util.h" | ||
|
||
|
||
WL_EXPORT void | ||
wl_egl_window_resize(struct wl_egl_window *egl_window, | ||
int width, int height, | ||
int dx, int dy) | ||
{ | ||
if (width <= 0 || height <= 0) | ||
return; | ||
|
||
egl_window->width = width; | ||
egl_window->height = height; | ||
egl_window->dx = dx; | ||
egl_window->dy = dy; | ||
|
||
if (egl_window->resize_callback) | ||
egl_window->resize_callback(egl_window, egl_window->driver_private); | ||
} | ||
|
||
WL_EXPORT struct wl_egl_window * | ||
wl_egl_window_create(struct wl_surface *surface, | ||
int width, int height) | ||
{ | ||
struct wl_egl_window *egl_window; | ||
|
||
if (width <= 0 || height <= 0) | ||
return NULL; | ||
|
||
egl_window = calloc(1, sizeof *egl_window); | ||
if (!egl_window) | ||
return NULL; | ||
|
||
/* Cast away the constness to set the version number. | ||
* | ||
* We want the const notation since it gives an explicit | ||
* feedback to the backend implementation, should it try to | ||
* change it. | ||
* | ||
* The latter in itself is not too surprising as these days APIs | ||
* tend to provide bidirectional version field. | ||
*/ | ||
intptr_t *version = (intptr_t *)&egl_window->version; | ||
*version = WL_EGL_WINDOW_VERSION; | ||
|
||
egl_window->surface = surface; | ||
|
||
egl_window->width = width; | ||
egl_window->height = height; | ||
|
||
return egl_window; | ||
} | ||
|
||
WL_EXPORT void | ||
wl_egl_window_destroy(struct wl_egl_window *egl_window) | ||
{ | ||
if (egl_window->destroy_window_callback) | ||
egl_window->destroy_window_callback(egl_window->driver_private); | ||
free(egl_window); | ||
} | ||
|
||
WL_EXPORT void | ||
wl_egl_window_get_attached_size(struct wl_egl_window *egl_window, | ||
int *width, int *height) | ||
{ | ||
if (width) | ||
*width = egl_window->attached_width; | ||
if (height) | ||
*height = egl_window->attached_height; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,6 +59,7 @@ | |
|
||
#include <wayland-client.h> | ||
#include <wayland-android-client-protocol.h> | ||
#include <wayland-egl-core.h> | ||
#include "linux-dmabuf-unstable-v1-client-protocol.h" | ||
#include "presentation-time-client-protocol.h" | ||
#include "xdg-shell-client-protocol.h" | ||
|
@@ -399,6 +400,8 @@ destroy_window(struct window *window, bool keep) | |
wl_subsurface_destroy(window->subsurfaces[it->first]); | ||
wl_surface_destroy(it->second); | ||
} | ||
if (window->egl_window) | ||
wl_egl_window_destroy(window->egl_window); | ||
if (window->xdg_toplevel) | ||
xdg_toplevel_destroy(window->xdg_toplevel); | ||
if (window->xdg_surface) | ||
|
@@ -412,10 +415,15 @@ destroy_window(struct window *window, bool keep) | |
window->isActive = false; | ||
else | ||
free(window); | ||
|
||
if (!window->appID.empty()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use after free. |
||
const std::string prop = std::string("waydroid.open_window.") + window->appID; | ||
property_set(prop.c_str(), "0"); | ||
} | ||
} | ||
|
||
struct window * | ||
create_window(struct display *display, bool with_dummy, std::string appID, std::string taskID) | ||
create_window(struct display *display, bool with_egl_window, std::string appID, std::string taskID, const int width, const int height) | ||
{ | ||
struct window *window = new struct window(); | ||
if (!window) | ||
|
@@ -426,6 +434,7 @@ create_window(struct display *display, bool with_dummy, std::string appID, std:: | |
window->surface = wl_compositor_create_surface(display->compositor); | ||
window->taskID = taskID; | ||
window->isActive = true; | ||
window->egl_window = nullptr; | ||
|
||
if (display->wm_base) { | ||
window->xdg_surface = | ||
|
@@ -479,29 +488,15 @@ create_window(struct display *display, bool with_dummy, std::string appID, std:: | |
} else { | ||
assert(0); | ||
} | ||
/* | ||
* We should create a dummy transparent 1x1 buffer in 0x0 location | ||
* This allows us to set initial location of windows by setting them as subsurface | ||
* and ovarally helps is moving surfaces | ||
* | ||
* TODO: Drop this hack | ||
*/ | ||
if (with_dummy) { | ||
int fd = syscall(SYS_memfd_create, "buffer", 0); | ||
ftruncate(fd, 4); | ||
void *shm_data = mmap(NULL, 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); | ||
if (shm_data == MAP_FAILED) { | ||
ALOGE("mmap failed"); | ||
close(fd); | ||
exit(1); | ||
} | ||
struct wl_shm_pool *pool = wl_shm_create_pool(display->shm, fd, 4); | ||
struct wl_buffer *buffer_shm = wl_shm_pool_create_buffer(pool, 0, 1, 1, 4, WL_SHM_FORMAT_ARGB8888); | ||
wl_shm_pool_destroy(pool); | ||
close(fd); | ||
wl_surface_attach(window->surface, buffer_shm, 0, 0); | ||
wl_surface_damage(window->surface, 0, 0, 1, 1); | ||
|
||
if (with_egl_window) { | ||
window->egl_window = wl_egl_window_create(window->surface, width, height); | ||
} | ||
|
||
window->appID = appID; | ||
std::string prop = std::string("waydroid.open_window.") + appID; | ||
property_set(prop.c_str(), "1"); | ||
|
||
return window; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're not removing the window from the list, which leads to crash. Also, I'd rather use
destroy_window
instead of freeing directly.