Fix for devices without EGL_KHR_surfaceless_context support

This commit is contained in:
Twaik Yont 2019-08-20 18:45:35 +03:00
parent c4af642a71
commit bd707e9ba5
17 changed files with 167 additions and 104 deletions

View File

@ -2,4 +2,5 @@ Android NDK: WARNING:/home/twaik/TermuxX11/app/src/main/jni/lorie/Android.mk:lor
Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES Android NDK: This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES
Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the Android NDK: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
Android NDK: current module Android NDK: current module
make: `/home/twaik/TermuxX11/app/build/intermediates/ndkBuild/debug/obj/local/armeabi-v7a/liblorie.so' is up to date. [armeabi-v7a] Compile++ thumb: lorie <= egl-helper.cpp
[armeabi-v7a] SharedLibrary : liblorie.so

View File

@ -33,13 +33,6 @@
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes" /> <output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/compileDebugUnitTestJavaWithJavac/classes" />
<exclude-output /> <exclude-output />
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/libxkbcommon/xkbcommon/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/libxkbcommon/xkbcommon/src/compose" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/libxkbcommon/xkbcommon/src/xkbcomp" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/lorie/backend/android" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/lorie" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/lorie/scanner" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni/lorie/utils" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
@ -58,7 +51,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
@ -66,7 +58,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
@ -74,7 +65,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
@ -82,7 +72,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
@ -90,7 +79,6 @@
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
@ -98,10 +86,9 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/.externalNativeBuild" /> <sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/build/generated/not_namespaced_r_class_sources" /> <excludeFolder url="file://$MODULE_DIR$/build/generated/not_namespaced_r_class_sources" />
<excludeFolder url="file://$MODULE_DIR$/build/generated/source/r" /> <excludeFolder url="file://$MODULE_DIR$/build/generated/source/r" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotation_processor_list" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotation_processor_list" />

View File

@ -20,14 +20,12 @@
<service <service
android:name=".LorieService" android:name=".LorieService"
android:enabled="true" android:enabled="true"
android:exported="false" android:exported="false"/>
android:persistent="true" />
<service <service
android:name=".LorieTestService" android:name=".LorieTestService"
android:enabled="true" android:enabled="true"
android:exported="true" android:exported="true"
android:process="com.termux.x11.separated" android:process="com.termux.x11.separated"/>
android:persistent="true" />
<activity android:name=".MainActivity" <activity android:name=".MainActivity"
android:theme="@style/NoActionBar" android:theme="@style/NoActionBar"
android:launchMode="singleInstance" android:launchMode="singleInstance"

View File

@ -13,6 +13,7 @@ import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.widget.HorizontalScrollView; import android.widget.HorizontalScrollView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -24,11 +25,13 @@ public class AdditionalKeyboardView extends HorizontalScrollView implements View
private final static int KEYCODE_BASE = 300; private final static int KEYCODE_BASE = 300;
public final static int PREFERENCES_KEY = KEYCODE_BASE + 1; public final static int PREFERENCES_KEY = KEYCODE_BASE + 1;
public final static int KEY_HEIGHT_DP = 35; public final static int KEY_HEIGHT_DP = 35;
Context ctx;
View targetView = null; private boolean softKbdVisible;
View.OnKeyListener targetListener = null; private Context ctx;
int density; private View targetView = null;
LinearLayout root; private View.OnKeyListener targetListener = null;
private int density;
private LinearLayout root;
public AdditionalKeyboardView(Context context) { public AdditionalKeyboardView(Context context) {
super(context); super(context);
init(context); init(context);
@ -71,10 +74,11 @@ public class AdditionalKeyboardView extends HorizontalScrollView implements View
int heightDiff = getRootView().getHeight() - (r.bottom - r.top); int heightDiff = getRootView().getHeight() - (r.bottom - r.top);
float dp = heightDiff/ mScreenDensity; float dp = heightDiff/ mScreenDensity;
int visibility = (dp > MAGIC_NUMBER)?View.VISIBLE:View.INVISIBLE; int visibility = (dp > MAGIC_NUMBER)?View.VISIBLE:View.INVISIBLE;
softKbdVisible = (visibility == View.VISIBLE);
if (getVisibility() == visibility) return; if (getVisibility() == visibility) return;
if (visibility == View.VISIBLE) if (softKbdVisible)
setY(r.bottom - r.top - getHeight()); setY(r.bottom - r.top - getHeight());
setVisibility(visibility); setVisibility(visibility);
} }

View File

@ -74,6 +74,7 @@ public class LoriePreferences extends AppCompatActivity implements SharedPrefere
addPreferencesFromResource(R.xml.preferences); addPreferencesFromResource(R.xml.preferences);
String showImeEnabled = Settings.Secure.getString(getActivity().getContentResolver(), SHOW_IME_WITH_HARD_KEYBOARD); String showImeEnabled = Settings.Secure.getString(getActivity().getContentResolver(), SHOW_IME_WITH_HARD_KEYBOARD);
if (showImeEnabled == null) showImeEnabled = "0";
SharedPreferences.Editor p = getPreferenceManager().getSharedPreferences().edit(); SharedPreferences.Editor p = getPreferenceManager().getSharedPreferences().edit();
p.putBoolean("showIMEWhileExternalConnected", showImeEnabled.equals("1")); p.putBoolean("showIMEWhileExternalConnected", showImeEnabled.equals("1"));
p.apply(); p.apply();

View File

@ -315,6 +315,7 @@ public class LorieService extends Service {
svc.pointerButton(TouchParser.BTN_RIGHT, (e.getAction() == KeyEvent.ACTION_DOWN) ? TouchParser.ACTION_DOWN : TouchParser.ACTION_UP); svc.pointerButton(TouchParser.BTN_RIGHT, (e.getAction() == KeyEvent.ACTION_DOWN) ? TouchParser.ACTION_DOWN : TouchParser.ACTION_UP);
rightPressed = (e.getAction() == KeyEvent.ACTION_DOWN); rightPressed = (e.getAction() == KeyEvent.ACTION_DOWN);
} else if (e.getAction() == KeyEvent.ACTION_UP) { } else if (e.getAction() == KeyEvent.ACTION_UP) {
if (act.kbd!=null) act.kbd.requestFocus();
KeyboardUtils.toggleKeyboardVisibility(act); KeyboardUtils.toggleKeyboardVisibility(act);
} }
return true; return true;

View File

@ -26,6 +26,8 @@ public:
void get_keymap(int *fd, int *size) override; void get_keymap(int *fd, int *size) override;
void window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height); void window_change_callback(EGLNativeWindowType win, uint32_t width, uint32_t height, uint32_t physical_width, uint32_t physical_height);
void layout_change_callback(char *layout); void layout_change_callback(char *layout);
void egl_after_init();
LorieEGLHelper helper; LorieEGLHelper helper;
@ -39,11 +41,19 @@ public:
LorieBackendAndroid::LorieBackendAndroid() LorieBackendAndroid::LorieBackendAndroid()
: self(&LorieCompositor::start, this) {} : self(&LorieCompositor::start, this) {}
void LorieBackendAndroid::egl_after_init() {
renderer.init();
}
void LorieBackendAndroid::backend_init() { void LorieBackendAndroid::backend_init() {
if (!helper.init(EGL_DEFAULT_DISPLAY)) { if (!helper.init(EGL_DEFAULT_DISPLAY)) {
LOGE("Failed to initialize EGL context"); LOGE("Failed to initialize EGL context");
} }
helper.onInit = std::bind(std::mem_fn(&LorieBackendAndroid::egl_after_init), this);
if (xkb_context == nullptr) { if (xkb_context == nullptr) {
xkb_context = xkb_context_new((enum xkb_context_flags) 0); xkb_context = xkb_context_new((enum xkb_context_flags) 0);
if (xkb_context == nullptr) { if (xkb_context == nullptr) {
@ -185,13 +195,9 @@ JNI_DECLARE(LorieService, windowChanged)(JNIEnv *env, jobject __unused instance,
LorieBackendAndroid *b = fromLong(jcompositor); LorieBackendAndroid *b = fromLong(jcompositor);
EGLNativeWindowType win = ANativeWindow_fromSurface(env, jsurface); EGLNativeWindowType win = ANativeWindow_fromSurface(env, jsurface);
if (win == nullptr) {
LOGE("Surface is invalid");
return;
}
LOGV("JNI: window is changed: %p(%p) %dx%d (%dmm x %dmm)", win, jsurface, width, height, mmWidth, mmHeight);
b->queue.call(&LorieBackendAndroid::window_change_callback, b, win, width, height, mmWidth, mmHeight); b->queue.call(&LorieBackendAndroid::window_change_callback, b, win, width, height, mmWidth, mmHeight);
LOGV("JNI: window is changed: %p(%p) %dx%d (%dmm x %dmm)", win, jsurface, width, height, mmWidth, mmHeight);
} }
extern "C" JNIEXPORT void JNICALL extern "C" JNIEXPORT void JNICALL

View File

@ -37,6 +37,9 @@ public:
private: private:
LorieEGLHelper helper; LorieEGLHelper helper;
X11Window win; X11Window win;
void onInit();
void onUninit();
}; };
void Backtrace(); void Backtrace();
@ -127,9 +130,21 @@ static void proc(int fd, uint32_t mask, void *data) {
that->processEvents(); that->processEvents();
} }
void LorieBackendX11::onInit() {
renderer.init();
}
void LorieBackendX11::onUninit() {
renderer.uninit();
}
void LorieBackendX11::backend_init() { void LorieBackendX11::backend_init() {
win.createWindow (WINDOW_WIDTH, WINDOW_HEIGHT); win.createWindow (WINDOW_WIDTH, WINDOW_HEIGHT);
helper.init(win.x_dpy); helper.init(win.x_dpy);
helper.onInit = std::bind(std::mem_fn(&LorieBackendX11::onInit), this);
helper.onUninit = std::bind(std::mem_fn(&LorieBackendX11::onUninit), this);
helper.setWindow(win.window); helper.setWindow(win.window);
renderer.resize(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/DPI*25.4, WINDOW_HEIGHT/DPI*25.4); renderer.resize(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/DPI*25.4, WINDOW_HEIGHT/DPI*25.4);

View File

@ -28,8 +28,8 @@ wrapper(keyboard_keymap_changed),
#undef wrapper #undef wrapper
renderer(*this), renderer(*this),
toplevel(toplevel_surface), toplevel(renderer.toplevel_surface),
cursor(cursor_surface), cursor(renderer.cursor_surface),
client_created_listener(*this) {} client_created_listener(*this) {}
int proc(int fd, uint32_t mask, void *data) { int proc(int fd, uint32_t mask, void *data) {
@ -57,7 +57,6 @@ void LorieCompositor::start() {
wl_resource_t::global_create<LorieShell>(display, this); wl_resource_t::global_create<LorieShell>(display, this);
backend_init(); backend_init();
renderer.init();
wl_display_run(display); wl_display_run(display);
} }
@ -81,18 +80,11 @@ void LorieCompositor::real_terminate() {
} }
void LorieCompositor::set_toplevel(LorieSurface *surface) { void LorieCompositor::set_toplevel(LorieSurface *surface) {
LOGV("Setting surface %p as toplevel", surface); renderer.set_toplevel(surface);
toplevel_surface = surface;
output_redraw();
} }
void LorieCompositor::set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y) { void LorieCompositor::set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y) {
LOGV("Setting surface %p as cursor", surface); renderer.set_cursor(surface, hotspot_x, hotspot_y);
cursor_surface = surface;
renderer.hotspot_x = hotspot_x;
renderer.hotspot_y = hotspot_y;
output_redraw();
} }
void LorieCompositor::real_output_redraw() { void LorieCompositor::real_output_redraw() {

View File

@ -1,5 +1,6 @@
#include <log.h> #include <log.h>
#include <lorie-egl-helper.hpp> #include <lorie-egl-helper.hpp>
#include <GLES2/gl2.h>
static char* eglGetErrorText(int code) { static char* eglGetErrorText(int code) {
switch(eglGetError()) { switch(eglGetError()) {
@ -78,7 +79,7 @@ bool LorieEGLHelper::init(EGLNativeDisplayType display) {
return false; return false;
} }
if (eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx) != EGL_TRUE) { if (eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONFIG_KHR) != EGL_TRUE) {
LOGE("LorieEGLHelper::init : eglMakeCurrent failed: %s", eglGetErrorText(eglGetError())); LOGE("LorieEGLHelper::init : eglMakeCurrent failed: %s", eglGetErrorText(eglGetError()));
return false; return false;
} }
@ -87,9 +88,10 @@ bool LorieEGLHelper::init(EGLNativeDisplayType display) {
} }
bool LorieEGLHelper::setWindow(EGLNativeWindowType window) { bool LorieEGLHelper::setWindow(EGLNativeWindowType window) {
LOGV("Trying to use window %p", window);
if (sfc != EGL_NO_SURFACE) { if (sfc != EGL_NO_SURFACE) {
if (eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx) != EGL_TRUE) { if (eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) {
LOGE("LorieEGLHelper::setWindow : eglMakeCurrent failed: %s", eglGetErrorText(eglGetError())); LOGE("LorieEGLHelper::setWindow : eglMakeCurrent (EGL_NO_SURFACE) failed: %s", eglGetErrorText(eglGetError()));
return false; return false;
} }
if (eglDestroySurface(dpy, sfc) != EGL_TRUE) { if (eglDestroySurface(dpy, sfc) != EGL_TRUE) {
@ -97,20 +99,35 @@ bool LorieEGLHelper::setWindow(EGLNativeWindowType window) {
return false; return false;
} }
}; };
sfc = EGL_NO_SURFACE;
win = window; win = window;
if (win == EGL_NO_WINDOW) return true; if (win == EGL_NO_WINDOW) {
if (onUninit != nullptr) onUninit();
return true;
}
sfc = eglCreateWindowSurface(dpy, cfg, win, NULL); sfc = eglCreateWindowSurface(dpy, cfg, win, NULL);
if (sfc == EGL_NO_SURFACE) { if (sfc == EGL_NO_SURFACE) {
LOGE("LorieEGLHelper::setWindow : eglCreateWindowSurface failed: %s", eglGetErrorText(eglGetError())); LOGE("LorieEGLHelper::setWindow : eglCreateWindowSurface failed: %s", eglGetErrorText(eglGetError()));
if (onUninit != nullptr) onUninit();
return false; return false;
} }
if (eglMakeCurrent(dpy, sfc, sfc, ctx) != EGL_TRUE) { if (eglMakeCurrent(dpy, sfc, sfc, ctx) != EGL_TRUE) {
LOGE("LorieEGLHelper::setWindow : eglMakeCurrent failed: %s", eglGetErrorText(eglGetError())); LOGE("LorieEGLHelper::setWindow : eglMakeCurrent failed: %s", eglGetErrorText(eglGetError()));
if (onUninit != nullptr) onUninit();
return false; return false;
} }
glClearColor(0.f, 0.f, 0.f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
swap();
if (onInit != nullptr)
onInit();
return true; return true;
} }

View File

@ -40,8 +40,7 @@ class LorieSurface: public wl_surface_t {
public: public:
void on_destroy() override {}; void on_destroy() override {};
void on_create() override {}; void on_create() override {};
uint32_t width = 0, height = 0;
uint32_t x = 0, y = 0; uint32_t x = 0, y = 0;
LorieTexture texture; LorieTexture texture;
struct wl_resource *buffer = NULL; struct wl_resource *buffer = NULL;

View File

@ -77,9 +77,6 @@ private:
struct LorieClient* get_toplevel_client(); struct LorieClient* get_toplevel_client();
uint32_t next_serial(); uint32_t next_serial();
LorieSurface* toplevel_surface = nullptr;
LorieSurface* cursor_surface = nullptr;
struct { struct {
uint32_t depressed = 0, latched = 0, locked = 0, group = 0; uint32_t depressed = 0, latched = 0, locked = 0, group = 0;

View File

@ -1,5 +1,6 @@
#include <EGL/egl.h> #include <EGL/egl.h>
#include <EGL/eglext.h> #include <EGL/eglext.h>
#include <functional>
#if defined(__ANDROID__) #if defined(__ANDROID__)
#define EGL_NO_WINDOW nullptr #define EGL_NO_WINDOW nullptr
@ -15,6 +16,9 @@ public:
EGLSurface sfc = EGL_NO_SURFACE; EGLSurface sfc = EGL_NO_SURFACE;
EGLContext ctx = EGL_NO_CONTEXT; EGLContext ctx = EGL_NO_CONTEXT;
EGLNativeWindowType win = EGL_NO_WINDOW; EGLNativeWindowType win = EGL_NO_WINDOW;
std::function<void()> onInit = nullptr;
std::function<void()> onUninit = nullptr;
bool init(EGLNativeDisplayType display); bool init(EGLNativeDisplayType display);
bool setWindow(EGLNativeWindowType window); bool setWindow(EGLNativeWindowType window);

View File

@ -1,13 +1,16 @@
#pragma once #pragma once
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <limits.h> #include <limits.h>
#include "LorieImpls.hpp"
class LorieCompositor; class LorieCompositor;
class LorieSurface;
class LorieRenderer { class LorieRenderer {
public: public:
LorieRenderer(LorieCompositor& compositor); LorieRenderer(LorieCompositor& compositor);
void requestRedraw(); void requestRedraw();
void init(); void init();
void uninit();
uint32_t width = 1024; uint32_t width = 1024;
uint32_t height = 600; uint32_t height = 600;
@ -25,6 +28,12 @@ public:
private: private:
static void idleDraw(void *data); static void idleDraw(void *data);
LorieCompositor& compositor; LorieCompositor& compositor;
void set_toplevel(LorieSurface *surface);
void set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y);
LorieSurface* toplevel_surface = nullptr;
LorieSurface* cursor_surface = nullptr;
struct wl_event_source *idle = NULL; struct wl_event_source *idle = NULL;
void drawCursor(); void drawCursor();
@ -33,20 +42,25 @@ private:
GLuint gvPos = 0; GLuint gvPos = 0;
GLuint gvCoords = 0; GLuint gvCoords = 0;
GLuint gvTextureSamplerHandle = 0; GLuint gvTextureSamplerHandle = 0;
bool ready = false;
friend class LorieTexture; friend class LorieTexture;
friend class LorieCompositor;
}; };
class LorieTexture { class LorieTexture {
private: private:
LorieRenderer* r = nullptr; LorieRenderer* r = nullptr;
bool damaged = false;
public: public:
LorieTexture(); LorieTexture();
uint32_t width, height; uint32_t width, height;
void *data = nullptr;
void set_data(LorieRenderer* renderer, uint32_t width, uint32_t height, void *data);
void damage(int32_t x, int32_t y, int32_t width, int32_t height);
void uninit(); void uninit();
void reinit(LorieRenderer* renderer, uint32_t _width, uint32_t _height); void reinit();
bool valid(); bool valid();
void upload(void *data);
private: private:
GLuint id = UINT_MAX; GLuint id = UINT_MAX;
void draw(float x0, float y0, float x1, float y1); void draw(float x0, float y0, float x1, float y1);

View File

@ -128,7 +128,8 @@ void LorieRenderer::init() {
} }
gvPos = (GLuint) glGetAttribLocation(gTextureProgram, "position"); checkGlError("glGetAttribLocation"); gvPos = (GLuint) glGetAttribLocation(gTextureProgram, "position"); checkGlError("glGetAttribLocation");
gvCoords = (GLuint) glGetAttribLocation(gTextureProgram, "texCoords"); checkGlError("glGetAttribLocation"); gvCoords = (GLuint) glGetAttribLocation(gTextureProgram, "texCoords"); checkGlError("glGetAttribLocation");
gvTextureSamplerHandle = (GLuint) glGetUniformLocation(gTextureProgram, "texture"); checkGlError("glGetAttribLocation"); gvTextureSamplerHandle = (GLuint) glGetUniformLocation(gTextureProgram, "texture"); checkGlError("glGetAttribLocation");
ready = true;
redraw(); redraw();
} }
@ -176,6 +177,23 @@ void LorieRenderer::setCursorVisibility(bool visibility) {
cursorVisible = visibility; cursorVisible = visibility;
} }
void LorieRenderer::set_toplevel(LorieSurface *surface) {
LOGV("Setting surface %p as toplevel", surface);
if (toplevel_surface) toplevel_surface->texture.uninit();
toplevel_surface = surface;
requestRedraw();
}
void LorieRenderer::set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y) {
LOGV("Setting surface %p as cursor", surface);
if (cursor_surface) cursor_surface->texture.uninit();
cursor_surface = surface;
this->hotspot_x = hotspot_x;
this->hotspot_y = hotspot_y;
requestRedraw();
}
void LorieRenderer::idleDraw(void *data) { void LorieRenderer::idleDraw(void *data) {
LorieRenderer* r = static_cast<LorieRenderer*> (data); LorieRenderer* r = static_cast<LorieRenderer*> (data);
@ -183,17 +201,21 @@ void LorieRenderer::idleDraw(void *data) {
} }
void LorieRenderer::drawCursor() { void LorieRenderer::drawCursor() {
if (compositor.toplevel == NULL || compositor.cursor == NULL || !compositor.cursor->texture.valid()) return; if (toplevel_surface == NULL || cursor_surface == NULL) return;
LorieTexture& toplevel = compositor.toplevel->texture; LorieTexture& toplevel = compositor.toplevel->texture;
LorieTexture& cursor = compositor.cursor->texture; LorieTexture& cursor = compositor.cursor->texture;
if (!cursor.valid()) cursor.reinit();
if (!cursor.valid()) return;
float x, y, width, height, hs_x, hs_y; float x, y, width, height, hs_x, hs_y;
hs_x = ((float)hotspot_x)/toplevel.width*2; hs_x = ((float)hotspot_x)/toplevel.width*2;
hs_y = ((float)hotspot_y)/toplevel.height*2; hs_y = ((float)hotspot_y)/toplevel.height*2;
x = (((float)compositor.cursor->x)/toplevel.width)*2 - 1.0 - hs_x; x = (((float)compositor.cursor->x)/toplevel.width)*2 - 1.0 - hs_x;
y = (((float)compositor.cursor->y)/toplevel.height)*2 - 1.0 - hs_y; y = (((float)compositor.cursor->y)/toplevel.height)*2 - 1.0 - hs_y;
width = 2*((float)compositor.cursor->width)/toplevel.width; width = 2*((float)cursor.width)/toplevel.width;
height = 2*((float)compositor.cursor->height)/toplevel.height; height = 2*((float)cursor.height)/toplevel.height;
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
cursor.draw(x, y, x + width, y + height); cursor.draw(x, y, x + width, y + height);
@ -203,13 +225,16 @@ void LorieRenderer::drawCursor() {
void LorieRenderer::redraw() { void LorieRenderer::redraw() {
//LOGV("Redrawing screen"); //LOGV("Redrawing screen");
idle = NULL; idle = NULL;
if (!ready) return;
//#define RAND ((float)(rand()%256)/256) //#define RAND ((float)(rand()%256)/256)
//glClearColor(RAND, RAND, RAND, 1.0); checkGlError("glClearColor"); //glClearColor(RAND, RAND, RAND, 1.0); checkGlError("glClearColor");
glClearColor(0.f, 0.f, 0.f, 0.f); checkGlError("glClearColor"); glClearColor(0.f, 0.f, 0.f, 0.f); checkGlError("glClearColor");
glClear(GL_COLOR_BUFFER_BIT); checkGlError("glClear"); glClear(GL_COLOR_BUFFER_BIT); checkGlError("glClear");
if (compositor.toplevel && compositor.toplevel->texture.valid()) { if (toplevel_surface) {
compositor.toplevel->texture.draw(-1.0, -1.0, 1.0, 1.0); if (!toplevel_surface->texture.valid())
toplevel_surface->texture.reinit();
toplevel_surface->texture.draw(-1.0, -1.0, 1.0, 1.0);
} }
if (cursorVisible) if (cursorVisible)
@ -218,9 +243,19 @@ void LorieRenderer::redraw() {
compositor.swap_buffers(); compositor.swap_buffers();
} }
LorieRenderer::~LorieRenderer() { void LorieRenderer::uninit() {
ready = false;
LOGV("Destroying renderer (tid %d)", ::gettid());
glUseProgram(0); glUseProgram(0);
glDeleteProgram(gTextureProgram); glDeleteProgram(gTextureProgram);
gTextureProgram = gvPos = gvCoords = gvTextureSamplerHandle = 0;
if (toplevel_surface) toplevel_surface->texture.uninit();
if (cursor_surface) cursor_surface->texture.uninit();
}
LorieRenderer::~LorieRenderer() {
uninit();
} }
LorieTexture::LorieTexture(){ LorieTexture::LorieTexture(){
@ -237,12 +272,17 @@ void LorieTexture::uninit() {
r = nullptr; r = nullptr;
} }
void LorieTexture::reinit(LorieRenderer* renderer, uint32_t _width, uint32_t _height) { void LorieTexture::set_data(LorieRenderer* renderer, uint32_t width, uint32_t height, void *data) {
LOGV("Reinitializing texture to %dx%d", _width, _height);
uninit(); uninit();
r = renderer; LOGV("Reinitializing texture to %dx%d", width, height);
width = _width; this->r = renderer;
height = _height; this->width = width;
this->height = height;
this->data = data;
reinit();
}
void LorieTexture::reinit() {
glClearColor(0.f, 0.f, 0.f, 0.f); checkGlError("glClearColor"); glClearColor(0.f, 0.f, 0.f, 0.f); checkGlError("glClearColor");
glClear(GL_COLOR_BUFFER_BIT); checkGlError("glClear"); glClear(GL_COLOR_BUFFER_BIT); checkGlError("glClear");
@ -257,18 +297,13 @@ void LorieTexture::reinit(LorieRenderer* renderer, uint32_t _width, uint32_t _he
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); checkGlError("glTexImage2D"); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); checkGlError("glTexImage2D");
} }
void LorieTexture::upload(void *data) { void LorieTexture::damage(int32_t x, int32_t y, int32_t width, int32_t height) {
if (!valid()) return; damaged = true;
r->requestRedraw();
glActiveTexture(GL_TEXTURE0); checkGlError("glActiveTexture");
glBindTexture(GL_TEXTURE_2D, id); checkGlError("glBindTexture");
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
checkGlError("glTexSubImage2D");
} }
bool LorieTexture::valid() { bool LorieTexture::valid() {
return (id != UINT_MAX && r != nullptr); return (width != 0 && height != 0 && id != UINT_MAX && r != nullptr);
} }
void LorieTexture::draw(float x0, float y0, float x1, float y1) { void LorieTexture::draw(float x0, float y0, float x1, float y1) {
@ -284,6 +319,12 @@ void LorieTexture::draw(float x0, float y0, float x1, float y1) {
glUseProgram(r->gTextureProgram); checkGlError("glUseProgram"); glUseProgram(r->gTextureProgram); checkGlError("glUseProgram");
glBindTexture(GL_TEXTURE_2D, id); checkGlError("glBindTexture"); glBindTexture(GL_TEXTURE_2D, id); checkGlError("glBindTexture");
if (damaged) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
checkGlError("glTexSubImage2D");
damaged = false;
}
glVertexAttribPointer(r->gvPos, 3, GL_FLOAT, GL_FALSE, 20, coords); checkGlError("glVertexAttribPointer"); glVertexAttribPointer(r->gvPos, 3, GL_FLOAT, GL_FALSE, 20, coords); checkGlError("glVertexAttribPointer");
glVertexAttribPointer(r->gvCoords, 2, GL_FLOAT, GL_FALSE, 20, &coords[3]); checkGlError("glVertexAttribPointer"); glVertexAttribPointer(r->gvCoords, 2, GL_FLOAT, GL_FALSE, 20, &coords[3]); checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(r->gvPos); checkGlError("glEnableVertexAttribArray"); glEnableVertexAttribArray(r->gvPos); checkGlError("glEnableVertexAttribArray");

View File

@ -44,8 +44,8 @@ void LoriePointer::request_set_cursor(uint32_t serial,
void LoriePointer::send_enter() { void LoriePointer::send_enter() {
if (client == nullptr || (*client)->compositor.toplevel == nullptr) return; if (client == nullptr || (*client)->compositor.toplevel == nullptr) return;
wl_fixed_t x = wl_fixed_from_double ((*client)->compositor.toplevel->width/2); wl_fixed_t x = wl_fixed_from_double ((*client)->compositor.toplevel->texture.width/2);
wl_fixed_t y = wl_fixed_from_double ((*client)->compositor.toplevel->height/2); wl_fixed_t y = wl_fixed_from_double ((*client)->compositor.toplevel->texture.height/2);
wl_pointer_t::send_enter(next_serial(), *(*client)->compositor.toplevel, x, y); wl_pointer_t::send_enter(next_serial(), *(*client)->compositor.toplevel, x, y);
} }

View File

@ -2,34 +2,27 @@
#include <lorie-client.hpp> #include <lorie-client.hpp>
#include <lorie-renderer.hpp> #include <lorie-renderer.hpp>
void LorieSurface::request_attach(struct wl_resource *wl_buffer, int32_t x, int32_t y) { void LorieSurface::request_attach(struct wl_resource *buffer, int32_t x, int32_t y) {
if (client == nullptr) return; if (client == nullptr) return;
buffer = wl_buffer; LorieRenderer* renderer = &(*client)->compositor.renderer;
this->buffer = buffer;
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer); struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer);
if (shm_buffer == NULL) { if (shm_buffer == NULL) {
width = height = 0; texture.set_data(renderer, 0, 0, nullptr);
return; return;
} }
width = (uint32_t) wl_shm_buffer_get_width (shm_buffer); uint32_t width = (uint32_t) wl_shm_buffer_get_width (shm_buffer);
height = (uint32_t) wl_shm_buffer_get_height (shm_buffer); uint32_t height = (uint32_t) wl_shm_buffer_get_height (shm_buffer);
void *data = wl_shm_buffer_get_data(shm_buffer);
if (width == 0 || height == 0) {
texture.uninit();
return;
}
if (!texture.valid() || texture.set_data(renderer, width, height, data);
texture.width != width ||
texture.height != height) {
texture.reinit(&(*client)->compositor.renderer, width, height);
}
} }
void LorieSurface::request_damage(int32_t x, int32_t y, int32_t width, int32_t height) { void LorieSurface::request_damage(int32_t x, int32_t y, int32_t width, int32_t height) {
if (client == nullptr) return; if (client == nullptr) return;
(*client)->compositor.renderer.requestRedraw(); texture.damage(x, y, width, height);
} }
void LorieSurface::request_frame(uint32_t callback) { void LorieSurface::request_frame(uint32_t callback) {
@ -37,15 +30,8 @@ void LorieSurface::request_frame(uint32_t callback) {
} }
void LorieSurface::request_commit() { void LorieSurface::request_commit() {
if (!buffer) return; //if (!buffer) return;
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get (buffer); //wl_buffer_send_release (buffer);
if (texture.valid() && shm_buffer) {
void *data = wl_shm_buffer_get_data (shm_buffer);
if (data) {
texture.upload(data);
}
}
wl_buffer_send_release (buffer);
if (frame_callback) { if (frame_callback) {
wl_callback_send_done (frame_callback, LorieUtils::timestamp()); wl_callback_send_done (frame_callback, LorieUtils::timestamp());