[Libreoffice-commits] .: Branch 'feature/android' - 3 commits - sal/android vcl/android vcl/inc vcl/Library_vcl.mk
Michael Meeks
michael at kemper.freedesktop.org
Fri Jan 27 06:56:37 PST 2012
sal/android/android_native_app_glue.c | 24 +++
sal/android/lo-bootstrap.c | 18 +-
vcl/Library_vcl.mk | 1
vcl/android/androidinst.cxx | 226 +++++++++++++++++++++++++---------
vcl/inc/android/androidinst.hxx | 10 +
5 files changed, 215 insertions(+), 64 deletions(-)
New commits:
commit 7acf7c1fd5cddb5aa6210e178bfab924570667c7
Author: Michael Meeks <michael.meeks at suse.com>
Date: Fri Jan 27 14:51:40 2012 +0000
android: add EGL and pixel redrawing modes + start of 565 conversion
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index fa6093e..169107d 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -434,6 +434,7 @@ ifeq ($(GUIBASE),android)
$(eval $(call gb_Library_add_libs,vcl,\
-llog \
-landroid \
+ -lEGL -lGLESv1_CM \
-llo-bootstrap \
))
$(eval $(call gb_Library_add_defs,vcl,\
diff --git a/vcl/android/androidinst.cxx b/vcl/android/androidinst.cxx
index 5adc357..f011858 100644
--- a/vcl/android/androidinst.cxx
+++ b/vcl/android/androidinst.cxx
@@ -36,6 +36,9 @@
#include <osl/detail/android_native_app_glue.h>
#include <rtl/strbuf.hxx>
+#undef ANDROID_EGL
+#define ANDROID_PIXELS
+
class AndroidSalData : public SalGenericData
{
public:
@@ -74,7 +77,7 @@ static rtl::OString KeyMetaStateToString(int32_t nFlags)
return aStr.makeStringAndClear();
}
-static void BlitFrameRegionToWindow(ANativeWindow *pWindow,
+static void BlitFrameRegionToWindow(ANativeWindow_Buffer *pOutBuffer,
const basebmp::BitmapDeviceSharedPtr& aDev,
const ARect &rSrcRect,
int nDestX, int nDestY)
@@ -82,22 +85,6 @@ static void BlitFrameRegionToWindow(ANativeWindow *pWindow,
fprintf (stderr, "Blit frame #2 src %d,%d->%d,%d to position %d, %d\n",
rSrcRect.left, rSrcRect.top, rSrcRect.right, rSrcRect.bottom,
nDestX, nDestY);
- ARect aRect;
- ANativeWindow_Buffer aOutBuffer;
- memset ((void *)&aOutBuffer, 0, sizeof (aOutBuffer));
- fprintf (stderr, "pre lock\n");
- int32_t nRet = ANativeWindow_lock(pWindow, &aOutBuffer, &aRect);
- fprintf (stderr, "locked window %d returned rect: %d,%d->%d,%d "
- "buffer: %dx%d stride %d, format %d, bits %p\n",
- nRet, aRect.left, aRect.top, aRect.right, aRect.bottom,
- aOutBuffer.width, aOutBuffer.height, aOutBuffer.stride,
- aOutBuffer.format, aOutBuffer.bits);
- if (aOutBuffer.bits == NULL)
- {
- fprintf (stderr, "no buffer for locked window\n");
- ANativeWindow_unlockAndPost(pWindow);
- return;
- }
// FIXME: do some cropping goodness on aSrcRect to ensure no overflows etc.
ARect aSrcRect = rSrcRect;
@@ -105,53 +92,125 @@ static void BlitFrameRegionToWindow(ANativeWindow *pWindow,
basebmp::RawMemorySharedArray aSrcData = aDev->getBuffer();
unsigned char *pSrc = aSrcData.get();
+ // FIXME: we have WINDOW_FORMAT_RGB_565 = 4 ...
+
for (unsigned int y = 0; y < (unsigned int)(aSrcRect.bottom - aSrcRect.top); y++)
{
unsigned char *sp = ( pSrc + nStride * (y + aSrcRect.top) +
aSrcRect.left * 3 /* src pixel size */ );
- unsigned char *dp = ( (unsigned char *)aOutBuffer.bits +
- aOutBuffer.stride * (y + nDestY) +
- nDestX * 4 /* dest pixel size */ );
- fprintf (stderr, "y %d, sp %p dp %p\n", y, sp, dp);
- for (unsigned int x = 0; x < (unsigned int)(aSrcRect.right - aSrcRect.left); x++)
+
+ switch (pOutBuffer->format) {
+ case WINDOW_FORMAT_RGBA_8888:
+ case WINDOW_FORMAT_RGBX_8888:
+ {
+ unsigned char *dp = ( (unsigned char *)pOutBuffer->bits +
+ pOutBuffer->stride * 4 * (y + nDestY) +
+ nDestX * 4 /* dest pixel size */ );
+ fprintf (stderr, "y %d, sp %p dp %p\n", y, sp, dp);
+ for (unsigned int x = 0; x < (unsigned int)(aSrcRect.right - aSrcRect.left); x++)
+ {
+ dp[x*4 + 0] = sp[x*3 + 0]; // B
+ dp[x*4 + 1] = sp[x*3 + 1]; // G
+ dp[x*4 + 2] = sp[x*3 + 2]; // R
+ dp[x*4 + 3] = 255; // A
+ }
+ break;
+ }
+ case WINDOW_FORMAT_RGB_565:
{
- dp[x*4 + 0] = sp[x*3 + 0]; // B
- dp[x*4 + 1] = sp[x*3 + 1]; // G
- dp[x*4 + 2] = sp[x*3 + 2]; // R
- dp[x*4 + 3] = 255; // A
+ unsigned char *dp = ( (unsigned char *)pOutBuffer->bits +
+ pOutBuffer->stride * 2 * (y + nDestY) +
+ nDestX * 2 /* dest pixel size */ );
+ fprintf (stderr, "y %d, sp %p dp %p\n", y, sp, dp);
+ for (unsigned int x = 0; x < (unsigned int)(aSrcRect.right - aSrcRect.left); x++)
+ {
+ unsigned char b = sp[x*3 + 0]; // B
+ unsigned char g = sp[x*3 + 1]; // G
+ unsigned char r = sp[x*3 + 2]; // R
+ dp[x*2 + 0] = (r & 0xf8) | (g >> 5);
+ dp[x*2 + 1] = ((g & 0x1c) << 5) | ((b & 0xf8) >> 3);
+ }
+ break;
+ }
+ default:
+ fprintf (stderr, "unknown pixel format %d !\n", pOutBuffer->format);
+ break;
}
}
fprintf (stderr, "done blit!\n");
-#if 0
- // hard-code / guess at a format ...
- int32_t *p = (int32_t *)aBuffer.bits;
- for (int32_t y = 0; y < aBuffer.height; y++)
- {
- for (int32_t x = 0; x < aBuffer.stride / 4; x++)
- *p++ = (y << 24) + x;
- }
-#endif
-
- ANativeWindow_unlockAndPost(pWindow);
- fprintf (stderr, "done render!\n");
}
-void AndroidSalInstance::BlitFrameToWindow(ANativeWindow *pWindow,
+void AndroidSalInstance::BlitFrameToWindow(ANativeWindow_Buffer *pOutBuffer,
const basebmp::BitmapDeviceSharedPtr& aDev)
{
basegfx::B2IVector aDevSize = aDev->getSize();
- ARect aWhole = { 0, 0, 400, 400 }; // FIXME: aDevSize.getX(), aDevSize.getY() };
- BlitFrameRegionToWindow(pWindow, aDev, aWhole, 0, 0);
+ ARect aWhole = { 0, 0, aDevSize.getX(), aDevSize.getY() };
+ BlitFrameRegionToWindow(pOutBuffer, aDev, aWhole, 0, 0);
}
void AndroidSalInstance::RedrawWindows(ANativeWindow *pWindow)
{
- std::list< SalFrame* >::const_iterator it;
- for ( it = getFrames().begin(); it != getFrames().end(); it++ )
+ (void)pWindow;
+#ifdef ANDROID_PIXELS
+ ARect aRect;
+ ANativeWindow_Buffer aOutBuffer;
+ memset ((void *)&aOutBuffer, 0, sizeof (aOutBuffer));
+ fprintf (stderr, "pre lock #3\n");
+#endif
+
+#ifdef ANDROID_EGL
+ if (mxDisplay == EGL_NO_DISPLAY)
+ {
+ fprintf (stderr, "wait for the setup\n");
+ return;
+ }
+
+ EGLBoolean nRet = eglMakeCurrent(mxDisplay, mxSurface, mxSurface, mxContext);
+ fprintf (stderr, "make current context %d\n", nRet);
+
+ // Just fill the screen with a color.
+ static int a = 0;
+ a++;
+ glClearColor((a & 0x1) ? 1.0 : 0.0, (a & 0x2) ? 1.0 : 0.0, 0.0, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ eglSwapBuffers(mxDisplay, mxSurface);
+#endif // ANDROID_EGL
+
+#ifdef ANDROID_PIXELS
+ int32_t nRet = ANativeWindow_lock(pWindow, &aOutBuffer, &aRect);
+ fprintf (stderr, "locked window %d returned rect: %d,%d->%d,%d "
+ "buffer: %dx%d stride %d, format %d, bits %p\n",
+ nRet, aRect.left, aRect.top, aRect.right, aRect.bottom,
+ aOutBuffer.width, aOutBuffer.height, aOutBuffer.stride,
+ aOutBuffer.format, aOutBuffer.bits);
+
+#if 1 // pre-'clean' the buffer with cruft:
+ // hard-code / guess at a format ...
+ int32_t *p = (int32_t *)aOutBuffer.bits;
+ for (int32_t y = 0; y < aOutBuffer.height; y++)
{
- SvpSalFrame *pFrame = static_cast<SvpSalFrame *>(*it);
- BlitFrameToWindow (pWindow, pFrame->getDevice());
+ for (int32_t x = 0; x < aOutBuffer.stride / 2; x++)
+ *p++ = (y << 24) + x;
}
+#endif
+
+ if (aOutBuffer.bits != NULL)
+ {
+ std::list< SalFrame* >::const_iterator it;
+ for ( it = getFrames().begin(); it != getFrames().end(); it++ )
+ {
+ SvpSalFrame *pFrame = static_cast<SvpSalFrame *>(*it);
+ BlitFrameToWindow (&aOutBuffer, pFrame->getDevice());
+ }
+ }
+ else
+ fprintf (stderr, "no buffer for locked window\n");
+
+ ANativeWindow_unlockAndPost(pWindow);
+ fprintf (stderr, "done render!\n");
+#endif // ANDROID_PIXELS
+
mbQueueReDraw = false;
}
@@ -194,6 +253,61 @@ void AndroidSalInstance::onAppCmd (struct android_app* app, int32_t cmd)
fprintf (stderr, "we have an app window ! %p %dx%x (%d)\n",
pWindow, aRect.right, aRect.bottom,
ANativeWindow_getFormat(pWindow));
+
+#ifdef ANDROID_EGL
+ const EGLint attribs[] = {
+ EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
+ EGL_BLUE_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_RED_SIZE, 8,
+ EGL_NONE
+ };
+ EGLint w, h, format;
+ EGLint numConfigs;
+ EGLConfig config;
+ EGLSurface surface;
+ EGLContext context;
+
+ EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ eglInitialize(display, 0, 0);
+
+ /* Here, the application chooses the configuration it desires. In this
+ * sample, we have a very simplified selection process, where we pick
+ * the first EGLConfig that matches our criteria */
+ eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+
+ /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
+ * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
+ * As soon as we picked a EGLConfig, we can safely reconfigure the
+ * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
+ eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
+
+ ANativeWindow_setBuffersGeometry(mpApp->window, 0, 0, format);
+
+ surface = eglCreateWindowSurface(display, config, mpApp->window, NULL);
+ context = eglCreateContext(display, config, NULL, NULL);
+
+ if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
+ fprintf(stderr, "Unable to eglMakeCurrent");
+ break;
+ }
+
+ eglQuerySurface(display, surface, EGL_WIDTH, &w);
+ eglQuerySurface(display, surface, EGL_HEIGHT, &h);
+
+ mxDisplay = display;
+ mxContext = context;
+ mxSurface = surface;
+
+ // Initialize GL state:
+ // FIXME: surely all this glContext - **per-thread** - !
+
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
+ glEnable(GL_CULL_FACE);
+ glShadeModel(GL_SMOOTH);
+ glDisable(GL_DEPTH_TEST);
+#endif
break;
}
case APP_CMD_WINDOW_RESIZED:
@@ -210,7 +324,7 @@ void AndroidSalInstance::onAppCmd (struct android_app* app, int32_t cmd)
case APP_CMD_WINDOW_REDRAW_NEEDED:
{
fprintf (stderr, "redraw needed\n");
- mbQueueReDraw = true;
+ AndroidSalInstance::getInstance()->RedrawWindows (pWindow);
break;
}
@@ -283,31 +397,26 @@ extern "C" {
{
return AndroidSalInstance::getInstance()->onInputEvent(app, event);
}
- void onNativeWindowRedrawNeeded_cb(ANativeActivity * /* activity */,
- ANativeWindow *pWindow)
- {
- fprintf (stderr, "onNativeWindowRedrawNeeded_cb\n");
- AndroidSalInstance::getInstance()->RedrawWindows (pWindow);
- }
}
AndroidSalInstance::AndroidSalInstance( SalYieldMutex *pMutex )
: SvpSalInstance( pMutex )
, mpApp( NULL )
, mbQueueReDraw( false )
+ , mxDisplay( EGL_NO_DISPLAY )
+ , mxSurface( EGL_NO_SURFACE )
+ , mxContext( EGL_NO_CONTEXT )
{
mpApp = lo_get_app();
- fprintf (stderr, "created Android Sal Instance for app %p window %p\n",
+ fprintf (stderr, "created Android Sal Instance for app %p window %p thread: %d\n",
mpApp,
- mpApp ? mpApp->window : NULL);
+ mpApp ? mpApp->window : NULL,
+ (int)pthread_self());
if (mpApp)
{
pthread_mutex_lock (&mpApp->mutex);
mpApp->onAppCmd = onAppCmd_cb;
mpApp->onInputEvent = onInputEvent_cb;
- if (mpApp->window != NULL)
- onAppCmd_cb (mpApp, APP_CMD_INIT_WINDOW);
- mpApp->activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded_cb;
pthread_mutex_unlock (&mpApp->mutex);
}
}
@@ -331,7 +440,8 @@ void AndroidSalInstance::DoReleaseYield (int nTimeoutMS)
// release yield mutex
sal_uLong nAcquireCount = ReleaseYieldMutex();
- fprintf (stderr, "DoReleaseYield #2 %d ms\n", nTimeoutMS);
+ fprintf (stderr, "DoReleaseYield #2 %d thread: %d ms\n",
+ nTimeoutMS, (int)pthread_self());
void *outData = NULL;
int outFd = 0, outEvents = 0;
diff --git a/vcl/inc/android/androidinst.hxx b/vcl/inc/android/androidinst.hxx
index 8efb963..7372f75 100644
--- a/vcl/inc/android/androidinst.hxx
+++ b/vcl/inc/android/androidinst.hxx
@@ -30,6 +30,9 @@
#ifndef ANDROID_SALINST_H
#define ANDROID_SALINST_H
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+
#include <android/input.h>
#include <android/native_window.h>
#include <headless/svpinst.hxx>
@@ -37,7 +40,7 @@
class AndroidSalInstance : public SvpSalInstance
{
- void BlitFrameToWindow(ANativeWindow *pWindow,
+ void BlitFrameToWindow(ANativeWindow_Buffer *pOutBuffer,
const basebmp::BitmapDeviceSharedPtr& aDev);
public:
AndroidSalInstance( SalYieldMutex *pMutex );
@@ -58,6 +61,11 @@ protected:
virtual void DoReleaseYield( int nTimeoutMS );
struct android_app *mpApp;
bool mbQueueReDraw;
+
+private:
+ EGLDisplay mxDisplay;
+ EGLSurface mxSurface;
+ EGLContext mxContext;
};
#endif // ANDROID_SALINST_H
commit 51741668593d23a1b35beb6971e92ba648974f31
Author: Michael Meeks <michael.meeks at suse.com>
Date: Fri Jan 27 14:50:21 2012 +0000
android: attach as daemon with given JNI version, and don't exit.
diff --git a/sal/android/lo-bootstrap.c b/sal/android/lo-bootstrap.c
index 9c2c3da..eee5f1f 100644
--- a/sal/android/lo-bootstrap.c
+++ b/sal/android/lo-bootstrap.c
@@ -47,7 +47,7 @@
#include <android/log.h>
#include "uthash.h"
-
+#include <osl/thread.h>
#include "osl/detail/android-bootstrap.h"
#pragma GCC diagnostic ignored "-Wdeclaration-after-statement"
@@ -1482,16 +1482,25 @@ __attribute__ ((visibility("default")))
void
android_main(struct android_app* state)
{
- JNIEnv *env;
+ jint nRet;
+ JNIEnv *pEnv = NULL;
struct engine engine;
Dl_info lo_main_info;
+ JavaVMAttachArgs aArgs = {
+ JNI_VERSION_1_2,
+ "LibreOfficeThread",
+ NULL
+ };
+
+ fprintf (stderr, "android_main in thread: %d\n", (int)pthread_self());
if (sleep_time != 0) {
LOGI("android_main: Sleeping for %d seconds, start ndk-gdb NOW if that is your intention", sleep_time);
sleep(sleep_time);
}
- (*(*state->activity->vm)->AttachCurrentThread)(state->activity->vm, &env, 0);
+ nRet = (*(*state->activity->vm)->AttachCurrentThreadAsDaemon)(state->activity->vm, &pEnv, &aArgs);
+ fprintf (stderr, "attach thread returned %d %p\n", nRet, pEnv);
app = state;
@@ -1508,8 +1517,7 @@ android_main(struct android_app* state)
extract_files(UNPACK_TREE);
lo_main(lo_main_argc, lo_main_argv);
-
- exit(0);
+ fprintf (stderr, "exit android_main\n");
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 76bdcb53a57234cbd2d05acc557935e8175c7884
Author: Michael Meeks <michael.meeks at suse.com>
Date: Fri Jan 27 14:48:55 2012 +0000
android: push the redraw-needed command into the app thread & wait
diff --git a/sal/android/android_native_app_glue.c b/sal/android/android_native_app_glue.c
index cacc3bb..c01db3b 100644
--- a/sal/android/android_native_app_glue.c
+++ b/sal/android/android_native_app_glue.c
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <sys/resource.h>
+#include "osl/detail/android-bootstrap.h"
#include "osl/detail/android_native_app_glue.h"
#include <android/log.h>
@@ -143,6 +144,12 @@ void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
+ case APP_CMD_WINDOW_REDRAW_NEEDED:
+ LOGI("APP_CMD_WINDOW_REDRAW_NEEDED - post\n");
+ pthread_mutex_lock(&android_app->mutex);
+ pthread_cond_broadcast(&android_app->cond);
+ pthread_mutex_unlock(&android_app->mutex);
+ break;
case APP_CMD_SAVE_STATE:
LOGI("APP_CMD_SAVE_STATE\n");
@@ -303,6 +310,17 @@ static void android_app_set_window(struct android_app* android_app, ANativeWindo
pthread_mutex_unlock(&android_app->mutex);
}
+static void android_app_window_redraw_needed(struct android_app* android_app, ANativeWindow* window) {
+ pthread_mutex_lock(&android_app->mutex);
+ if (window != NULL) {
+ android_app_write_cmd(android_app, APP_CMD_WINDOW_REDRAW_NEEDED);
+ }
+ while (android_app->window != android_app->pendingWindow) {
+ pthread_cond_wait(&android_app->cond, &android_app->mutex);
+ }
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, cmd);
@@ -404,6 +422,11 @@ static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* wi
android_app_set_window((struct android_app*)activity->instance, NULL);
}
+static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) {
+ LOGI("onNativeWindowRedrawNeeded: %p -- %p\n", activity, window);
+ android_app_window_redraw_needed((struct android_app*)activity->instance, window);
+}
+
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
LOGI("InputQueueCreated: %p -- %p\n", activity, queue);
android_app_set_input((struct android_app*)activity->instance, queue);
@@ -428,6 +451,7 @@ __attribute__ ((visibility("default"))) void ANativeActivity_onCreate(ANativeAct
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
+ activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded;
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
More information about the Libreoffice-commits
mailing list