summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2018-03-05 22:57:33 +0000
committerMatthias Melcher <fltk@matthiasm.com>2018-03-05 22:57:33 +0000
commitb47db80af359e5ab3b2188573cbf42ee439a2be7 (patch)
treed765c679f19eec438e8cd03e1ff10289ba69357b /src/drivers
parent8c51282770f86800ea609fda8bddb0d54a84ec62 (diff)
Android: drawing behaves nice enough. Fl::flush seems to bring the expected results, although optimization is required at some point.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12710 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/Android/Fl_Android_Application.H12
-rw-r--r--src/drivers/Android/Fl_Android_Application.cxx62
-rw-r--r--src/drivers/Android/Fl_Android_Screen_Driver.H3
-rw-r--r--src/drivers/Android/Fl_Android_Screen_Driver.cxx15
-rw-r--r--src/drivers/Android/Fl_Android_Window_Driver.cxx2
5 files changed, 60 insertions, 34 deletions
diff --git a/src/drivers/Android/Fl_Android_Application.H b/src/drivers/Android/Fl_Android_Application.H
index 48573e7c1..f88d29c3c 100644
--- a/src/drivers/Android/Fl_Android_Application.H
+++ b/src/drivers/Android/Fl_Android_Application.H
@@ -121,14 +121,12 @@ public:
static void post_exec_cmd(int8_t cmd);
static inline ANativeWindow *native_window() { return pNativeWindow; }
- static inline ANativeWindow_Buffer &graphics_buffer() { return pNativeWindowBuffer; }
+ static inline ANativeWindow_Buffer &graphics_buffer() { return pApplicationWindowBuffer; }
static int destroy_requested() { return pDestroyRequested; }
static void set_on_app_cmd(void (*cmd)(int32_t cmd)) { pOnAppCmd = cmd; }
static void set_on_input_event(int32_t (*cmd)(AInputEvent* event)) { pOnInputEvent = cmd; }
- static bool lock_screen();
- static void unlock_and_post_screen();
- static bool screen_is_locked();
+ static void copy_screen();
protected:
static void free_saved_state();
@@ -138,6 +136,11 @@ protected:
static void process_cmd(struct android_poll_source* source);
static void* thread_entry(void* param);
+ static void allocate_screen();
+ static bool lock_screen();
+ static void unlock_and_post_screen();
+ static bool screen_is_locked();
+
static ANativeActivity *pActivity;
static AConfiguration *pConfig;
static void *pSavedState;
@@ -146,6 +149,7 @@ protected:
static AInputQueue *pInputQueue;
static ANativeWindow *pNativeWindow;
static ANativeWindow_Buffer pNativeWindowBuffer;
+ static ANativeWindow_Buffer pApplicationWindowBuffer;
static int pActivityState;
static int pDestroyRequested;
static void (*pOnAppCmd)(int32_t cmd);
diff --git a/src/drivers/Android/Fl_Android_Application.cxx b/src/drivers/Android/Fl_Android_Application.cxx
index 81988b4cd..59fa8483c 100644
--- a/src/drivers/Android/Fl_Android_Application.cxx
+++ b/src/drivers/Android/Fl_Android_Application.cxx
@@ -70,6 +70,7 @@ ANativeWindow* Fl_Android_Application::pNativeWindow = 0;
// Use this buffer for direct drawing access
ANativeWindow_Buffer Fl_Android_Application::pNativeWindowBuffer = { 0 };
+ANativeWindow_Buffer Fl_Android_Application::pApplicationWindowBuffer = { 0 };
// Current state of the app's activity. May be either APP_CMD_START,
// APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below.
@@ -367,6 +368,43 @@ void *Fl_Android_Application::thread_entry(void* param)
}
/**
+ * Allocate memory for our internal screen buffer.
+ *
+ * FIXME: everything is currently hardcoded to an 600x800 resolution
+ * TODO: react to screen changes
+ */
+void Fl_Android_Application::allocate_screen() {
+ pApplicationWindowBuffer.bits = calloc(600*800, 2); // one uint16_t per pixel
+ pApplicationWindowBuffer.width = 600;
+ pApplicationWindowBuffer.height = 800;
+ pApplicationWindowBuffer.stride = 600;
+ pApplicationWindowBuffer.format = WINDOW_FORMAT_RGB_565;
+}
+
+
+#include <FL/fl_draw.H>
+
+void Fl_Android_Application::copy_screen()
+{
+ if (lock_screen()) {
+
+ static int i = 0;
+ fl_color( (i&1) ? FL_RED : FL_GREEN);
+ fl_rectf(i*10, 600+i*10, 50, 50);
+ i++;
+ if (i>10) i = 0;
+
+ // TODO: there are endless possibilities to optimize the following code
+ // We can identify previously written buffers and copy only those pixels
+ // that actually changed.
+ memcpy(pNativeWindowBuffer.bits,
+ pApplicationWindowBuffer.bits,
+ 600*800*2);
+ unlock_and_post_screen();
+ }
+}
+
+/**
* Take ownership of screen memory for gaining write access.
*
* If the screen is already locked, it will not be locked again
@@ -386,25 +424,13 @@ bool Fl_Android_Application::lock_screen()
return false;
}
- // 190, 200, 280, 35
- ARect dirty = { .left=190, .top = 200, .right = 290, .bottom = 235 };
- if (ANativeWindow_lock(pNativeWindow, &pNativeWindowBuffer, &dirty) < 0) {
+ if (ANativeWindow_lock(pNativeWindow, &pNativeWindowBuffer, 0L) < 0) {
log_w("Unable to lock window buffer: Android won't lock.");
return false;
}
- log_w("Dirty rect is %d %d %d %d", dirty.left, dirty.top, dirty.right, dirty.bottom);
-
- ANativeWindow_Buffer buf;
- if (ANativeWindow_lock(pNativeWindow, &buf, &dirty) < 0) {
- log_w("Unable to lock 2nd window buffer: Android won't lock.");
- return false;
- }
-
return true;
}
-#include <FL/fl_draw.H>
-
/**
* Release screen memory ownership and give it back to the system.
*
@@ -416,12 +442,6 @@ void Fl_Android_Application::unlock_and_post_screen()
if (!screen_is_locked())
return;
- static int i = 0;
- fl_color( (i&1) ? FL_RED : FL_GREEN);
- fl_rectf(i*10, 700, 50, 50);
- i++;
- if (i>10) i = 0;
-
ANativeWindow_unlockAndPost(pNativeWindow);
pNativeWindowBuffer.bits = 0L; // avoid any misunderstandings...
}
@@ -679,12 +699,14 @@ void Fl_Android_Activity::onInputQueueDestroyed(ANativeActivity* activity, AInpu
void Fl_Android_Activity::create(ANativeActivity* activity, void* savedState,
size_t savedStateSize)
{
- static char *FLTK = "FLTK";
+ static const char *FLTK = "FLTK";
activity->instance = (void*)FLTK;
set_activity(activity);
set_callbacks();
+ allocate_screen(); // TODO: we may need to change this to when the actual screen is allocated
+
pthread_mutex_init(&pMutex, NULL);
pthread_cond_init(&pCond, NULL);
diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.H b/src/drivers/Android/Fl_Android_Screen_Driver.H
index 0aff97c04..7948c906f 100644
--- a/src/drivers/Android/Fl_Android_Screen_Driver.H
+++ b/src/drivers/Android/Fl_Android_Screen_Driver.H
@@ -58,7 +58,7 @@ protected:
#endif
public:
- Fl_Android_Screen_Driver() : Fl_Screen_Driver() { }
+ Fl_Android_Screen_Driver() : Fl_Screen_Driver(), pScreenContentChanged(false) { }
#if 0
Fl_WinAPI_Screen_Driver() : Fl_Screen_Driver() {
@@ -118,6 +118,7 @@ public:
virtual float desktop_scale_factor();
#endif
+ bool pScreenContentChanged;
};
diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.cxx b/src/drivers/Android/Fl_Android_Screen_Driver.cxx
index 1ffdc382a..3b6fdf677 100644
--- a/src/drivers/Android/Fl_Android_Screen_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Screen_Driver.cxx
@@ -372,17 +372,16 @@ void Fl_WinAPI_Screen_Driver::beep(int type)
#endif
/**
- * On Android, get access to screen memory, then flush(), then
- * release screen memory and post it to the physicla screen.
- *
- * Don't do anything if the screen wasn't previously locked by
- * any Fl_Window_Driver. We would just needlessly repost the same screen.
+ * On Android, we currently write into a memory buffer and copy
+ * the content to the screen.
*/
void Fl_Android_Screen_Driver::flush()
{
- if (Fl_Android_Application::screen_is_locked()) {
- Fl_Screen_Driver::flush();
- Fl_Android_Application::unlock_and_post_screen();
+ Fl_Screen_Driver::flush();
+ // FIXME: do this only if anything actually changed on screen!
+ if (pScreenContentChanged) {
+ Fl_Android_Application::copy_screen();
+ pScreenContentChanged = false;
}
}
diff --git a/src/drivers/Android/Fl_Android_Window_Driver.cxx b/src/drivers/Android/Fl_Android_Window_Driver.cxx
index fab8190db..dddd18c5d 100644
--- a/src/drivers/Android/Fl_Android_Window_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Window_Driver.cxx
@@ -77,7 +77,7 @@ void Fl_Android_Window_Driver::show()
void Fl_Android_Window_Driver::make_current()
{
- Fl_Android_Application::lock_screen();
+ ((Fl_Android_Screen_Driver*)Fl::screen_driver())->pScreenContentChanged = true;
}