Android fixes

This commit is contained in:
Vadim Lopatin 2016-04-20 16:54:21 +03:00
parent 1ac9601f47
commit 1911c75765
2 changed files with 108 additions and 62 deletions

View File

@ -15,17 +15,21 @@
* *
*/ */
version(Android):
import core.stdc.stdlib : malloc; import core.stdc.stdlib : malloc;
import core.stdc.string : memset; import core.stdc.string : memset;
import dlangui.core.logger; import dlangui.core.logger;
import dlangui.widgets.styles; import dlangui.widgets.styles;
import dlangui.graphics.drawbuf; import dlangui.graphics.drawbuf;
import dlangui.graphics.gldrawbuf;
import dlangui.graphics.glsupport;
//import dlangui.widgets.widget; //import dlangui.widgets.widget;
import dlangui.platforms.common.platform; import dlangui.platforms.common.platform;
import EGL.eglplatform : EGLint; //import EGL.eglplatform : EGLint;
import EGL.egl, GLES.gl; //import EGL.egl, GLES.gl;
import android.input, android.looper : ALooper_pollAll; import android.input, android.looper : ALooper_pollAll;
import android.native_window : ANativeWindow_setBuffersGeometry; import android.native_window : ANativeWindow_setBuffersGeometry;
@ -42,7 +46,10 @@ class AndroidWindow : Window {
/// show window /// show window
override void show() { override void show() {
// TODO // TODO
_visible = true;
_platform.drawWindow(this);
} }
bool _visible;
protected dstring _caption; protected dstring _caption;
/// returns window caption /// returns window caption
@ -99,6 +106,9 @@ class AndroidPlatform : Platform {
protected EGLContext _context; protected EGLContext _context;
protected int _width; protected int _width;
protected int _height; protected int _height;
protected ASensorManager* _sensorManager;
protected const(ASensor)* _accelerometerSensor;
protected ASensorEventQueue* _sensorEventQueue;
this(android_app* state) { this(android_app* state) {
@ -109,10 +119,10 @@ class AndroidPlatform : Platform {
state.onInputEvent = &engine_handle_input; state.onInputEvent = &engine_handle_input;
// Prepare to monitor accelerometer // Prepare to monitor accelerometer
_engine.sensorManager = ASensorManager_getInstance(); _sensorManager = ASensorManager_getInstance();
_engine.accelerometerSensor = ASensorManager_getDefaultSensor(_engine.sensorManager, _accelerometerSensor = ASensorManager_getDefaultSensor(_sensorManager,
ASENSOR_TYPE_ACCELEROMETER); ASENSOR_TYPE_ACCELEROMETER);
_engine.sensorEventQueue = ASensorManager_createEventQueue(_engine.sensorManager, _sensorEventQueue = ASensorManager_createEventQueue(_sensorManager,
state.looper, LOOPER_ID_USER, null, null); state.looper, LOOPER_ID_USER, null, null);
if (state.savedState != null) { if (state.savedState != null) {
@ -178,7 +188,9 @@ class AndroidPlatform : Platform {
eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h); eglQuerySurface(display, surface, EGL_HEIGHT, &h);
Log.i("surface created: ", _width, "x", _height);
_display = display; _display = display;
_context = context; _context = context;
_surface = surface; _surface = surface;
@ -187,31 +199,17 @@ class AndroidPlatform : Platform {
_engine.state.angle = 0; _engine.state.angle = 0;
// Initialize GL state. // Initialize GL state.
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); //glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
//glShadeModel(GL_SMOOTH); //glShadeModel(GL_SMOOTH);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
Log.i("calling initGLSupport");
initGLSupport(false);
return 0; return 0;
} }
/**
* Just the current frame in the display.
*/
void engine_draw_frame() {
if (_display == null) {
// No display.
return;
}
// Just fill the screen with a color.
glClearColor(_engine.state.x/_width, _engine.state.angle,
_engine.state.y/_height, 1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(_display, _surface);
}
/** /**
* Tear down the EGL context currently associated with the display. * Tear down the EGL context currently associated with the display.
*/ */
@ -260,7 +258,7 @@ class AndroidPlatform : Platform {
// The window is being shown, get it ready. // The window is being shown, get it ready.
if (_appstate.window != null) { if (_appstate.window != null) {
engine_init_display(); engine_init_display();
engine_draw_frame(); drawWindow();
} }
break; break;
case APP_CMD_TERM_WINDOW: case APP_CMD_TERM_WINDOW:
@ -269,24 +267,24 @@ class AndroidPlatform : Platform {
break; break;
case APP_CMD_GAINED_FOCUS: case APP_CMD_GAINED_FOCUS:
// When our app gains focus, we start monitoring the accelerometer. // When our app gains focus, we start monitoring the accelerometer.
if (_engine.accelerometerSensor != null) { if (_accelerometerSensor != null) {
ASensorEventQueue_enableSensor(_engine.sensorEventQueue, ASensorEventQueue_enableSensor(_sensorEventQueue,
_engine.accelerometerSensor); _accelerometerSensor);
// We'd like to get 60 events per second (in us). // We'd like to get 60 events per second (in us).
ASensorEventQueue_setEventRate(_engine.sensorEventQueue, ASensorEventQueue_setEventRate(_sensorEventQueue,
_engine.accelerometerSensor, (1000L/60)*1000); _accelerometerSensor, (1000L/60)*1000);
} }
break; break;
case APP_CMD_LOST_FOCUS: case APP_CMD_LOST_FOCUS:
// When our app loses focus, we stop monitoring the accelerometer. // When our app loses focus, we stop monitoring the accelerometer.
// This is to avoid consuming battery while not being used. // This is to avoid consuming battery while not being used.
if (_engine.accelerometerSensor != null) { if (_accelerometerSensor != null) {
ASensorEventQueue_disableSensor(_engine.sensorEventQueue, ASensorEventQueue_disableSensor(_sensorEventQueue,
_engine.accelerometerSensor); _accelerometerSensor);
} }
// Also stop animating. // Also stop animating.
_engine.animating = 0; _engine.animating = 0;
engine_draw_frame(); drawWindow();
break; break;
default: default:
break; break;
@ -307,7 +305,6 @@ class AndroidPlatform : Platform {
override Window createWindow(dstring windowCaption, Window parent, uint flags = WindowFlag.Resizable, uint width = 0, uint height = 0) { override Window createWindow(dstring windowCaption, Window parent, uint flags = WindowFlag.Resizable, uint width = 0, uint height = 0) {
AndroidWindow w = new AndroidWindow(this); AndroidWindow w = new AndroidWindow(this);
_windows ~= w; _windows ~= w;
_activeWindow = w;
return w; return w;
} }
@ -324,7 +321,49 @@ class AndroidPlatform : Platform {
break; break;
} }
} }
_activeWindow = (_windows.length > 0 ? _windows[$ - 1] : null); }
@property AndroidWindow activeWindow() {
for (int i = cast(int)_windows.length - 1; i >= 0; i++)
if (_windows[i]._visible)
return _windows[i];
return null;
}
GLDrawBuf _drawbuf;
void drawWindow(AndroidWindow w = null) {
if (w is null)
w = activeWindow;
else if (!(activeWindow is w))
return;
if (_display == null) {
// No display.
return;
}
// Just fill the screen with a color.
if (!w) {
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
} else {
w.onResize(_width, _height);
glDisable(GL_DEPTH_TEST);
glViewport(0, 0, _width, _height);
float a = 1.0f;
float r = ((w.backgroundColor >> 16) & 255) / 255.0f;
float g = ((w.backgroundColor >> 8) & 255) / 255.0f;
float b = ((w.backgroundColor >> 0) & 255) / 255.0f;
glClearColor(r, g, b, a);
glClear(GL_COLOR_BUFFER_BIT);
if (!_drawbuf)
_drawbuf = new GLDrawBuf(_width, _height);
_drawbuf.resize(_width, _height);
_drawbuf.beforeDrawing();
w.onDraw(_drawbuf);
_drawbuf.afterDrawing();
}
eglSwapBuffers(_display, _surface);
} }
/** /**
@ -352,9 +391,9 @@ class AndroidPlatform : Platform {
// If a sensor has data, process it now. // If a sensor has data, process it now.
if (ident == LOOPER_ID_USER) { if (ident == LOOPER_ID_USER) {
if (_engine.accelerometerSensor != null) { if (_accelerometerSensor != null) {
ASensorEvent event; ASensorEvent event;
while (ASensorEventQueue_getEvents(_engine.sensorEventQueue, while (ASensorEventQueue_getEvents(_sensorEventQueue,
&event, 1) > 0) { &event, 1) > 0) {
LOGI("accelerometer: x=%f y=%f z=%f", LOGI("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y, event.acceleration.x, event.acceleration.y,
@ -378,7 +417,7 @@ class AndroidPlatform : Platform {
// Drawing is throttled to the screen update rate, so there // Drawing is throttled to the screen update rate, so there
// is no need to do timing here. // is no need to do timing here.
engine_draw_frame(); drawWindow();
} }
} }
} }
@ -422,9 +461,9 @@ struct saved_state {
struct engine { struct engine {
//android_app* app; //android_app* app;
ASensorManager* sensorManager; //ASensorManager* sensorManager;
const(ASensor)* accelerometerSensor; //const(ASensor)* accelerometerSensor;
ASensorEventQueue* sensorEventQueue; //ASensorEventQueue* sensorEventQueue;
int animating; int animating;
//EGLDisplay display; //EGLDisplay display;

View File

@ -680,12 +680,12 @@ bool initGLSupport(bool legacy = false) {
if (_glSupport && _glSupport.valid) if (_glSupport && _glSupport.valid)
return true; return true;
version(Android) { version(Android) {
Log.d("initGLSupport");
} else { } else {
static bool DERELICT_GL3_RELOADED; static bool DERELICT_GL3_RELOADED;
static bool gl3ReloadedOk; static bool gl3ReloadedOk;
static bool glReloadedOk; static bool glReloadedOk;
if (!DERELICT_GL3_RELOADED) { if (!DERELICT_GL3_RELOADED) {
DERELICT_GL3_RELOADED = true; DERELICT_GL3_RELOADED = true;
try { try {
Log.v("Reloading DerelictGL3"); Log.v("Reloading DerelictGL3");
@ -716,6 +716,7 @@ bool initGLSupport(bool legacy = false) {
legacy = false; legacy = false;
} }
if (!_glSupport) { if (!_glSupport) {
Log.d("glSupport not initialized: trying to create");
_glSupport = new GLSupport(legacy); _glSupport = new GLSupport(legacy);
if (_glSupport.valid || _glSupport.initShaders()) { if (_glSupport.valid || _glSupport.initShaders()) {
Log.v("shaders are ok"); Log.v("shaders are ok");
@ -724,15 +725,19 @@ bool initGLSupport(bool legacy = false) {
return true; return true;
} else { } else {
Log.e("Failed to compile shaders"); Log.e("Failed to compile shaders");
// try opposite legacy flag version (Android) {
if (_glSupport.legacyMode == legacy) { // do not recreate legacy mode
Log.i("Trying to reinit GLSupport with legacy flag ", !legacy); } else {
_glSupport = new GLSupport(!legacy); // try opposite legacy flag
if (_glSupport.valid || _glSupport.initShaders()) { if (_glSupport.legacyMode == legacy) {
Log.v("shaders are ok"); Log.i("Trying to reinit GLSupport with legacy flag ", !legacy);
setOpenglEnabled(); _glSupport = new GLSupport(!legacy);
Log.v("OpenGL is initialized ok"); if (_glSupport.valid || _glSupport.initShaders()) {
return true; Log.v("shaders are ok");
setOpenglEnabled();
Log.v("OpenGL is initialized ok");
return true;
}
} }
} }
} }
@ -754,13 +759,14 @@ final class GLSupport {
@property bool legacyMode() { return _legacyMode; } @property bool legacyMode() { return _legacyMode; }
this(bool legacy = false) { this(bool legacy = false) {
version (Android) { version (Android) {
} else { Log.d("creating GLSupport");
if (legacy && !glLightfv) { } else {
Log.w("GLSupport legacy API is not supported"); if (legacy && !glLightfv) {
legacy = false; Log.w("GLSupport legacy API is not supported");
} legacy = false;
} }
}
_legacyMode = legacy; _legacyMode = legacy;
} }
@ -773,6 +779,7 @@ final class GLSupport {
} }
bool initShaders() { bool initShaders() {
Log.i("initShaders() is called");
if (_solidFillProgram is null) { if (_solidFillProgram is null) {
Log.v("Compiling solid fill program"); Log.v("Compiling solid fill program");
_solidFillProgram = new SolidFillProgram(); _solidFillProgram = new SolidFillProgram();