diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2018-03-05 22:57:33 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2018-03-05 22:57:33 +0000 |
| commit | b47db80af359e5ab3b2188573cbf42ee439a2be7 (patch) | |
| tree | d765c679f19eec438e8cd03e1ff10289ba69357b /src/drivers | |
| parent | 8c51282770f86800ea609fda8bddb0d54a84ec62 (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.H | 12 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Application.cxx | 62 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Screen_Driver.H | 3 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Screen_Driver.cxx | 15 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Window_Driver.cxx | 2 |
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; } |
