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: or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the
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" />
<exclude-output />
<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/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" />
@ -58,7 +51,6 @@
<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/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/shaders" isTestSource="false" />
<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/aidl" 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/shaders" isTestSource="true" />
<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/aidl" 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/shaders" isTestSource="true" />
<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/aidl" 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/shaders" isTestSource="false" />
<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/aidl" 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/shaders" isTestSource="true" />
<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/aidl" 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/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/source/r" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotation_processor_list" />

View File

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

View File

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

View File

@ -74,6 +74,7 @@ public class LoriePreferences extends AppCompatActivity implements SharedPrefere
addPreferencesFromResource(R.xml.preferences);
String showImeEnabled = Settings.Secure.getString(getActivity().getContentResolver(), SHOW_IME_WITH_HARD_KEYBOARD);
if (showImeEnabled == null) showImeEnabled = "0";
SharedPreferences.Editor p = getPreferenceManager().getSharedPreferences().edit();
p.putBoolean("showIMEWhileExternalConnected", showImeEnabled.equals("1"));
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);
rightPressed = (e.getAction() == KeyEvent.ACTION_DOWN);
} else if (e.getAction() == KeyEvent.ACTION_UP) {
if (act.kbd!=null) act.kbd.requestFocus();
KeyboardUtils.toggleKeyboardVisibility(act);
}
return true;

View File

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

View File

@ -37,6 +37,9 @@ public:
private:
LorieEGLHelper helper;
X11Window win;
void onInit();
void onUninit();
};
void Backtrace();
@ -127,9 +130,21 @@ static void proc(int fd, uint32_t mask, void *data) {
that->processEvents();
}
void LorieBackendX11::onInit() {
renderer.init();
}
void LorieBackendX11::onUninit() {
renderer.uninit();
}
void LorieBackendX11::backend_init() {
win.createWindow (WINDOW_WIDTH, WINDOW_HEIGHT);
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);
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
renderer(*this),
toplevel(toplevel_surface),
cursor(cursor_surface),
toplevel(renderer.toplevel_surface),
cursor(renderer.cursor_surface),
client_created_listener(*this) {}
int proc(int fd, uint32_t mask, void *data) {
@ -57,7 +57,6 @@ void LorieCompositor::start() {
wl_resource_t::global_create<LorieShell>(display, this);
backend_init();
renderer.init();
wl_display_run(display);
}
@ -81,18 +80,11 @@ void LorieCompositor::real_terminate() {
}
void LorieCompositor::set_toplevel(LorieSurface *surface) {
LOGV("Setting surface %p as toplevel", surface);
toplevel_surface = surface;
output_redraw();
renderer.set_toplevel(surface);
}
void LorieCompositor::set_cursor(LorieSurface *surface, uint32_t hotspot_x, uint32_t hotspot_y) {
LOGV("Setting surface %p as cursor", surface);
cursor_surface = surface;
renderer.hotspot_x = hotspot_x;
renderer.hotspot_y = hotspot_y;
output_redraw();
renderer.set_cursor(surface, hotspot_x, hotspot_y);
}
void LorieCompositor::real_output_redraw() {

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,16 @@
#pragma once
#include <GLES2/gl2.h>
#include <limits.h>
#include "LorieImpls.hpp"
class LorieCompositor;
class LorieSurface;
class LorieRenderer {
public:
LorieRenderer(LorieCompositor& compositor);
void requestRedraw();
void init();
void uninit();
uint32_t width = 1024;
uint32_t height = 600;
@ -25,6 +28,12 @@ public:
private:
static void idleDraw(void *data);
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;
void drawCursor();
@ -33,20 +42,25 @@ private:
GLuint gvPos = 0;
GLuint gvCoords = 0;
GLuint gvTextureSamplerHandle = 0;
bool ready = false;
friend class LorieTexture;
friend class LorieCompositor;
};
class LorieTexture {
private:
LorieRenderer* r = nullptr;
bool damaged = false;
public:
LorieTexture();
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 reinit(LorieRenderer* renderer, uint32_t _width, uint32_t _height);
void reinit();
bool valid();
void upload(void *data);
private:
GLuint id = UINT_MAX;
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");
gvCoords = (GLuint) glGetAttribLocation(gTextureProgram, "texCoords"); checkGlError("glGetAttribLocation");
gvTextureSamplerHandle = (GLuint) glGetUniformLocation(gTextureProgram, "texture"); checkGlError("glGetAttribLocation");
gvTextureSamplerHandle = (GLuint) glGetUniformLocation(gTextureProgram, "texture"); checkGlError("glGetAttribLocation");
ready = true;
redraw();
}
@ -176,6 +177,23 @@ void LorieRenderer::setCursorVisibility(bool 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) {
LorieRenderer* r = static_cast<LorieRenderer*> (data);
@ -183,17 +201,21 @@ void LorieRenderer::idleDraw(void *data) {
}
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& cursor = compositor.cursor->texture;
if (!cursor.valid()) cursor.reinit();
if (!cursor.valid()) return;
float x, y, width, height, hs_x, hs_y;
hs_x = ((float)hotspot_x)/toplevel.width*2;
hs_y = ((float)hotspot_y)/toplevel.height*2;
x = (((float)compositor.cursor->x)/toplevel.width)*2 - 1.0 - hs_x;
y = (((float)compositor.cursor->y)/toplevel.height)*2 - 1.0 - hs_y;
width = 2*((float)compositor.cursor->width)/toplevel.width;
height = 2*((float)compositor.cursor->height)/toplevel.height;
width = 2*((float)cursor.width)/toplevel.width;
height = 2*((float)cursor.height)/toplevel.height;
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
cursor.draw(x, y, x + width, y + height);
@ -203,13 +225,16 @@ void LorieRenderer::drawCursor() {
void LorieRenderer::redraw() {
//LOGV("Redrawing screen");
idle = NULL;
if (!ready) return;
//#define RAND ((float)(rand()%256)/256)
//glClearColor(RAND, RAND, RAND, 1.0); checkGlError("glClearColor");
glClearColor(0.f, 0.f, 0.f, 0.f); checkGlError("glClearColor");
glClear(GL_COLOR_BUFFER_BIT); checkGlError("glClear");
if (compositor.toplevel && compositor.toplevel->texture.valid()) {
compositor.toplevel->texture.draw(-1.0, -1.0, 1.0, 1.0);
if (toplevel_surface) {
if (!toplevel_surface->texture.valid())
toplevel_surface->texture.reinit();
toplevel_surface->texture.draw(-1.0, -1.0, 1.0, 1.0);
}
if (cursorVisible)
@ -218,9 +243,19 @@ void LorieRenderer::redraw() {
compositor.swap_buffers();
}
LorieRenderer::~LorieRenderer() {
void LorieRenderer::uninit() {
ready = false;
LOGV("Destroying renderer (tid %d)", ::gettid());
glUseProgram(0);
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(){
@ -237,12 +272,17 @@ void LorieTexture::uninit() {
r = nullptr;
}
void LorieTexture::reinit(LorieRenderer* renderer, uint32_t _width, uint32_t _height) {
LOGV("Reinitializing texture to %dx%d", _width, _height);
void LorieTexture::set_data(LorieRenderer* renderer, uint32_t width, uint32_t height, void *data) {
uninit();
r = renderer;
width = _width;
height = _height;
LOGV("Reinitializing texture to %dx%d", width, height);
this->r = renderer;
this->width = width;
this->height = height;
this->data = data;
reinit();
}
void LorieTexture::reinit() {
glClearColor(0.f, 0.f, 0.f, 0.f); checkGlError("glClearColor");
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");
}
void LorieTexture::upload(void *data) {
if (!valid()) return;
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");
void LorieTexture::damage(int32_t x, int32_t y, int32_t width, int32_t height) {
damaged = true;
r->requestRedraw();
}
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) {
@ -284,6 +319,12 @@ void LorieTexture::draw(float x0, float y0, float x1, float y1) {
glUseProgram(r->gTextureProgram); checkGlError("glUseProgram");
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->gvCoords, 2, GL_FLOAT, GL_FALSE, 20, &coords[3]); checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(r->gvPos); checkGlError("glEnableVertexAttribArray");

View File

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

View File

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