From 289b9b62372ef52a06113b83dfb870e2c2fb325a Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Fri, 9 Jul 2010 11:44:11 -0700 Subject: Add ANativeWindow API for directly drawing to the surface bits. Also other cleanup and fixes: - We now properly set the default window format to 565. - New APIs to set the window format and flags from native code. - Tweaked glue for simpler handling of the "destroy" message. - Um, other stuff. Change-Id: Id7790a21a2fa9a19b91854d225324a7c1e7c6ade --- native/android/Android.mk | 7 ++-- native/android/activity.cpp | 0 native/android/native_activity.cpp | 31 ++++++++++++++++ native/android/native_window.cpp | 58 +++++++++++++++++++++++++++--- native/glue/threaded_app/threaded_app.c | 4 ++- native/include/android/native_activity.h | 5 +++ native/include/android/native_window.h | 43 ++++++++++++++++++---- native/include/android/native_window_jni.h | 40 +++++++++++++++++++++ native/include/android/rect.h | 36 +++++++++++++++++++ native/include/android/window.h | 58 ++++++++++++++++++++++++++++++ native/include/android_glue/threaded_app.h | 13 ++++--- 11 files changed, 276 insertions(+), 19 deletions(-) delete mode 100644 native/android/activity.cpp create mode 100644 native/android/native_activity.cpp create mode 100644 native/include/android/native_window_jni.h create mode 100644 native/include/android/rect.h create mode 100644 native/include/android/window.h (limited to 'native') diff --git a/native/android/Android.mk b/native/android/Android.mk index 376c64f..509a379 100644 --- a/native/android/Android.mk +++ b/native/android/Android.mk @@ -6,17 +6,18 @@ include $(CLEAR_VARS) # our source files # LOCAL_SRC_FILES:= \ - activity.cpp \ input.cpp \ looper.cpp \ + native_activity.cpp \ native_window.cpp LOCAL_SHARED_LIBRARIES := \ - libandroid_runtime \ libcutils \ libutils \ libbinder \ - libui + libui \ + libsurfaceflinger_client \ + libandroid_runtime LOCAL_C_INCLUDES += \ frameworks/base/native/include \ diff --git a/native/android/activity.cpp b/native/android/activity.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/native/android/native_activity.cpp b/native/android/native_activity.cpp new file mode 100644 index 0000000..509cc33 --- /dev/null +++ b/native/android/native_activity.cpp @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "native_activity" +#include + +#include + +using namespace android; + +void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format) { + android_NativeActivity_setWindowFormat(activity, format); +} + +void ANativeActivity_setWindowFlags(ANativeActivity* activity, + uint32_t addFlags, uint32_t removeFlags) { + android_NativeActivity_setWindowFlags(activity, addFlags, addFlags|removeFlags); +} diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp index 448cbfc..bada078 100644 --- a/native/android/native_window.cpp +++ b/native/android/native_window.cpp @@ -17,10 +17,27 @@ #define LOG_TAG "Surface" #include -#include +#include #include +#include -using android::Surface; +using namespace android; + +ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface) { + sp win = android_Surface_getNativeWindow(env, surface); + if (win != NULL) { + win->incStrong((void*)ANativeWindow_acquire); + } + return win.get(); +} + +void ANativeWindow_acquire(ANativeWindow* window) { + window->incStrong((void*)ANativeWindow_acquire); +} + +void ANativeWindow_release(ANativeWindow* window) { + window->decStrong((void*)ANativeWindow_acquire); +} static int32_t getWindowProp(ANativeWindow* window, int what) { int value; @@ -41,7 +58,40 @@ int32_t ANativeWindow_getFormat(ANativeWindow* window) { } int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, - int32_t height, int32_t format) { - native_window_set_buffers_geometry(window, width, height, format); + int32_t height) { + native_window_set_buffers_geometry(window, width, height, 0); return 0; } + +int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, + ARect* inOutDirtyBounds) { + Region dirtyRegion; + Region* dirtyParam = NULL; + if (inOutDirtyBounds != NULL) { + dirtyRegion.set(*(Rect*)inOutDirtyBounds); + dirtyParam = &dirtyRegion; + } + + Surface::SurfaceInfo info; + status_t res = static_cast(window)->lock(&info, dirtyParam); + if (res != OK) { + return -1; + } + + outBuffer->width = (int32_t)info.w; + outBuffer->height = (int32_t)info.h; + outBuffer->stride = (int32_t)info.s; + outBuffer->format = (int32_t)info.format; + outBuffer->bits = info.bits; + + if (inOutDirtyBounds != NULL) { + *inOutDirtyBounds = dirtyRegion.getBounds(); + } + + return 0; +} + +int32_t ANativeWindow_unlockAndPost(ANativeWindow* window) { + status_t res = static_cast(window)->unlockAndPost(); + return res == android::OK ? 0 : -1; +} diff --git a/native/glue/threaded_app/threaded_app.c b/native/glue/threaded_app/threaded_app.c index c9cae8b..16c905c 100644 --- a/native/glue/threaded_app/threaded_app.c +++ b/native/glue/threaded_app/threaded_app.c @@ -51,7 +51,7 @@ int8_t android_app_read_cmd(struct android_app* android_app) { return -1; } -void android_app_exec_cmd(struct android_app* android_app, int8_t cmd) { +int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd) { switch (cmd) { case APP_CMD_INPUT_CHANGED: LOGI("APP_CMD_INPUT_CHANGED\n"); @@ -93,6 +93,8 @@ void android_app_exec_cmd(struct android_app* android_app, int8_t cmd) { android_app->destroyRequested = 1; break; } + + return android_app->destroyRequested ? 0 : 1; } static void* android_app_entry(void* param) { diff --git a/native/include/android/native_activity.h b/native/include/android/native_activity.h index a31c5af..d0ff052 100644 --- a/native/include/android/native_activity.h +++ b/native/include/android/native_activity.h @@ -192,6 +192,11 @@ typedef void ANativeActivity_createFunc(ANativeActivity* activity, */ extern ANativeActivity_createFunc ANativeActivity_onCreate; +void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format); + +void ANativeActivity_setWindowFlags(ANativeActivity* activity, + uint32_t addFlags, uint32_t removeFlags); + #ifdef __cplusplus }; #endif diff --git a/native/include/android/native_window.h b/native/include/android/native_window.h index 678ba3d..7599d7e 100644 --- a/native/include/android/native_window.h +++ b/native/include/android/native_window.h @@ -14,10 +14,11 @@ * limitations under the License. */ - #ifndef ANDROID_NATIVE_WINDOW_H #define ANDROID_NATIVE_WINDOW_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -34,6 +35,27 @@ enum { struct ANativeWindow; typedef struct ANativeWindow ANativeWindow; +typedef struct ANativeWindow_Buffer { + int32_t width; + int32_t height; + int32_t stride; + int32_t format; + void* bits; + + uint32_t reserved[6]; +} ANativeWindow_Buffer; + +/** + * Acquire a reference on the given ANativeWindow object. This prevents the object + * from being deleted until the reference is removed. + */ +void ANativeWindow_acquire(ANativeWindow* window); + +/** + * Remove a reference that was previously acquired with ANativeWindow_acquire(). + */ +void ANativeWindow_release(ANativeWindow* window); + /* * Return the current width in pixels of the window surface. Returns a * negative value on error. @@ -60,13 +82,22 @@ int32_t ANativeWindow_getFormat(ANativeWindow* window); * window's physical size, then it buffer will be scaled to match that size * when compositing it to the screen. * - * The format may be one of the window format constants above. - * - * For all of these parameters, if 0 is supplied than the window's base + * For all of these parameters, if 0 is supplied then the window's base * value will come back in force. */ -int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, - int32_t height, int32_t format); +int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width, int32_t height); + +/** + * Lock the window's next drawing surface for writing. + */ +int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, + ARect* inOutDirtyBounds); + +/** + * Unlock the window's drawing surface after previously locking it, + * posting the new buffer to the display. + */ +int32_t ANativeWindow_unlockAndPost(ANativeWindow* window); #ifdef __cplusplus }; diff --git a/native/include/android/native_window_jni.h b/native/include/android/native_window_jni.h new file mode 100644 index 0000000..b9e72ef --- /dev/null +++ b/native/include/android/native_window_jni.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_NATIVE_WINDOW_JNI_H +#define ANDROID_NATIVE_WINDOW_JNI_H + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Return the ANativeWindow associated with a Java Surface object, + * for interacting with it through native code. This acquires a reference + * on the ANativeWindow that is returned; be sure to use ANativeWindow_release() + * when done with it so that it doesn't leak. + */ +ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface); + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_NATIVE_WINDOW_H diff --git a/native/include/android/rect.h b/native/include/android/rect.h new file mode 100644 index 0000000..3e81f53 --- /dev/null +++ b/native/include/android/rect.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_RECT_H +#define ANDROID_RECT_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ARect { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +} ARect; + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_RECT_H diff --git a/native/include/android/window.h b/native/include/android/window.h new file mode 100644 index 0000000..2ab192b --- /dev/null +++ b/native/include/android/window.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef ANDROID_WINDOW_H +#define ANDROID_WINDOW_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Window flags, as per the Java API at android.view.WindowManager.LayoutParams. + */ +enum { + AWINDOW_FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001, + AWINDOW_FLAG_DIM_BEHIND = 0x00000002, + AWINDOW_FLAG_BLUR_BEHIND = 0x00000004, + AWINDOW_FLAG_NOT_FOCUSABLE = 0x00000008, + AWINDOW_FLAG_NOT_TOUCHABLE = 0x00000010, + AWINDOW_FLAG_NOT_TOUCH_MODAL = 0x00000020, + AWINDOW_FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040, + AWINDOW_FLAG_KEEP_SCREEN_ON = 0x00000080, + AWINDOW_FLAG_LAYOUT_IN_SCREEN = 0x00000100, + AWINDOW_FLAG_LAYOUT_NO_LIMITS = 0x00000200, + AWINDOW_FLAG_FULLSCREEN = 0x00000400, + AWINDOW_FLAG_FORCE_NOT_FULLSCREEN = 0x00000800, + AWINDOW_FLAG_DITHER = 0x00001000, + AWINDOW_FLAG_SECURE = 0x00002000, + AWINDOW_FLAG_SCALED = 0x00004000, + AWINDOW_FLAG_IGNORE_CHEEK_PRESSES = 0x00008000, + AWINDOW_FLAG_LAYOUT_INSET_DECOR = 0x00010000, + AWINDOW_FLAG_ALT_FOCUSABLE_IM = 0x00020000, + AWINDOW_FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000, + AWINDOW_FLAG_SHOW_WHEN_LOCKED = 0x00080000, + AWINDOW_FLAG_SHOW_WALLPAPER = 0x00100000, + AWINDOW_FLAG_TURN_SCREEN_ON = 0x00200000, + AWINDOW_FLAG_DISMISS_KEYGUARD = 0x00400000, +}; + +#ifdef __cplusplus +}; +#endif + +#endif // ANDROID_WINDOW_H diff --git a/native/include/android_glue/threaded_app.h b/native/include/android_glue/threaded_app.h index 80de3bf..491389b 100644 --- a/native/include/android_glue/threaded_app.h +++ b/native/include/android_glue/threaded_app.h @@ -52,10 +52,6 @@ struct android_app { // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. int activityState; - // This is non-zero when the application's NativeActivity is being - // destroyed and waiting for the app thread to complete. - int destroyRequested; - // ------------------------------------------------- // Below are "private" implementation of the glue code. @@ -67,6 +63,10 @@ struct android_app { pthread_t thread; + // This is non-zero when the application's NativeActivity is being + // destroyed and waiting for the app thread to complete. + int destroyRequested; + int running; int destroyed; AInputQueue* pendingInputQueue; @@ -158,8 +158,11 @@ int8_t android_app_read_cmd(struct android_app* android_app); /** * Call with the command returned by android_app_read_cmd() to do the * default processing of the given command. + * + * Important: returns 0 if the app should exit. You must ALWAYS check for + * a zero return and, if found, exit your android_main() function. */ -void android_app_exec_cmd(struct android_app* android_app, int8_t cmd); +int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd); /** * This is the function that application code must implement, representing -- cgit v1.1