1 #ifdef MOZ_WIDGET_ANDROID
3 #include "AndroidNativeWindow.h"
6 // #define ANDROID_NATIVE_WINDOW_DEBUG
8 #if defined(ANDROID_NATIVE_WINDOW_DEBUG) || defined(DEBUG)
9 #define ALOG(args...) __android_log_print(ANDROID_LOG_INFO, "AndroidNativeWindow" , ## args)
11 #define ALOG(args...) ((void)0)
14 using namespace mozilla::gfx
;
15 using namespace mozilla::gl
;
16 using namespace mozilla
;
18 class NativeWindowLibrary
23 : fANativeWindow_fromSurface(nullptr)
24 , fANativeWindow_release(nullptr)
25 , fANativeWindow_setBuffersGeometry(nullptr)
26 , fANativeWindow_lock(nullptr)
27 , fANativeWindow_unlockAndPost(nullptr)
28 , fANativeWindow_getFormat(nullptr)
29 , fANativeWindow_getWidth(nullptr)
30 , fANativeWindow_getHeight(nullptr)
32 PRLibrary
* lib
= PR_LoadLibrary("libandroid.so");
34 fANativeWindow_fromSurface
= (pfnANativeWindow_fromSurface
)PR_FindSymbol(lib
, "ANativeWindow_fromSurface");
35 fANativeWindow_release
= (pfnANativeWindow_release
)PR_FindSymbol(lib
, "ANativeWindow_release");
36 fANativeWindow_setBuffersGeometry
= (pfnANativeWindow_setBuffersGeometry
)PR_FindSymbol(lib
, "ANativeWindow_setBuffersGeometry");
37 fANativeWindow_lock
= (pfnANativeWindow_lock
)PR_FindSymbol(lib
, "ANativeWindow_lock");
38 fANativeWindow_unlockAndPost
= (pfnANativeWindow_unlockAndPost
)PR_FindSymbol(lib
, "ANativeWindow_unlockAndPost");
39 fANativeWindow_getFormat
= (pfnANativeWindow_getFormat
)PR_FindSymbol(lib
, "ANativeWindow_getFormat");
40 fANativeWindow_getWidth
= (pfnANativeWindow_getWidth
)PR_FindSymbol(lib
, "ANativeWindow_getWidth");
41 fANativeWindow_getHeight
= (pfnANativeWindow_getHeight
)PR_FindSymbol(lib
, "ANativeWindow_getHeight");
44 void* ANativeWindow_fromSurface(JNIEnv
* aEnv
, jobject aSurface
) {
45 ALOG("%s: env=%p, surface=%p\n", __PRETTY_FUNCTION__
, aEnv
, aSurface
);
50 return fANativeWindow_fromSurface(aEnv
, aSurface
);
53 void ANativeWindow_release(void* aWindow
) {
54 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__
, aWindow
);
59 fANativeWindow_release(aWindow
);
62 bool ANativeWindow_setBuffersGeometry(void* aWindow
, int32_t aWidth
, int32_t aHeight
, int32_t aFormat
) {
63 ALOG("%s: window=%p, width=%d, height=%d, format=%d\n", __PRETTY_FUNCTION__
, aWindow
, aWidth
, aHeight
, aFormat
);
68 return fANativeWindow_setBuffersGeometry(aWindow
, aWidth
, aHeight
, (int32_t)aFormat
) == 0;
71 bool ANativeWindow_lock(void* aWindow
, void* out_buffer
, void*in_out_dirtyBounds
) {
72 ALOG("%s: window=%p, out_buffer=%p, in_out_dirtyBounds=%p\n", __PRETTY_FUNCTION__
,
73 aWindow
, out_buffer
, in_out_dirtyBounds
);
78 return fANativeWindow_lock(aWindow
, out_buffer
, in_out_dirtyBounds
) == 0;
81 bool ANativeWindow_unlockAndPost(void* aWindow
) {
82 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__
, aWindow
);
87 return fANativeWindow_unlockAndPost(aWindow
) == 0;
90 AndroidWindowFormat
ANativeWindow_getFormat(void* aWindow
) {
91 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__
, aWindow
);
93 return AndroidWindowFormat::Unknown
;
96 return (AndroidWindowFormat
)fANativeWindow_getFormat(aWindow
);
99 int32_t ANativeWindow_getWidth(void* aWindow
) {
100 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__
, aWindow
);
101 if (!Initialized()) {
105 return fANativeWindow_getWidth(aWindow
);
108 int32_t ANativeWindow_getHeight(void* aWindow
) {
109 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__
, aWindow
);
110 if (!Initialized()) {
114 return fANativeWindow_getHeight(aWindow
);
118 return fANativeWindow_fromSurface
&& fANativeWindow_release
&& fANativeWindow_setBuffersGeometry
119 && fANativeWindow_lock
&& fANativeWindow_unlockAndPost
&& fANativeWindow_getFormat
&& fANativeWindow_getWidth
120 && fANativeWindow_getHeight
;
125 typedef void* (*pfnANativeWindow_fromSurface
)(JNIEnv
* env
, jobject surface
);
126 pfnANativeWindow_fromSurface fANativeWindow_fromSurface
;
128 typedef void (*pfnANativeWindow_release
)(void* window
);
129 pfnANativeWindow_release fANativeWindow_release
;
131 typedef int32_t (*pfnANativeWindow_setBuffersGeometry
)(void* window
, int32_t width
, int32_t height
, int32_t format
);
132 pfnANativeWindow_setBuffersGeometry fANativeWindow_setBuffersGeometry
;
134 typedef int32_t (*pfnANativeWindow_lock
)(void *window
, void *out_buffer
, void *in_out_dirtyBounds
);
135 pfnANativeWindow_lock fANativeWindow_lock
;
137 typedef int32_t (*pfnANativeWindow_unlockAndPost
)(void *window
);
138 pfnANativeWindow_unlockAndPost fANativeWindow_unlockAndPost
;
140 typedef AndroidWindowFormat (*pfnANativeWindow_getFormat
)(void* window
);
141 pfnANativeWindow_getFormat fANativeWindow_getFormat
;
143 typedef int32_t (*pfnANativeWindow_getWidth
)(void* window
);
144 pfnANativeWindow_getWidth fANativeWindow_getWidth
;
146 typedef int32_t (*pfnANativeWindow_getHeight
)(void* window
);
147 pfnANativeWindow_getHeight fANativeWindow_getHeight
;
150 static NativeWindowLibrary
* sLibrary
= nullptr;
155 static bool initialized
= false;
158 sLibrary
= new NativeWindowLibrary();
160 initialized
= sLibrary
->Initialized();
169 /* static */ AndroidNativeWindow
*
170 AndroidNativeWindow::CreateFromSurface(JNIEnv
* aEnv
, jobject aSurface
)
173 ALOG("Not initialized");
177 void* window
= sLibrary
->ANativeWindow_fromSurface(aEnv
, aSurface
);
179 ALOG("Failed to create window from surface");
183 return new AndroidNativeWindow(window
);
186 AndroidNativeWindow::~AndroidNativeWindow()
188 if (EnsureInit() && mWindow
) {
189 sLibrary
->ANativeWindow_release(mWindow
);
195 AndroidNativeWindow::Size()
199 return IntSize(0, 0);
202 return IntSize(sLibrary
->ANativeWindow_getWidth(mWindow
), sLibrary
->ANativeWindow_getHeight(mWindow
));
206 AndroidNativeWindow::Format()
210 return AndroidWindowFormat::Unknown
;
213 return sLibrary
->ANativeWindow_getFormat(mWindow
);
217 AndroidNativeWindow::SetBuffersGeometry(int32_t aWidth
, int32_t aHeight
, AndroidWindowFormat aFormat
)
223 return sLibrary
->ANativeWindow_setBuffersGeometry(mWindow
, aWidth
, aHeight
, (int32_t)aFormat
);
227 AndroidNativeWindow::Lock(void** out_bits
,int32_t* out_width
, int32_t* out_height
,
228 int32_t* out_stride
, AndroidWindowFormat
* out_format
)
230 /* Copied from native_window.h in Android NDK (platform-9) */
231 typedef struct ANativeWindow_Buffer
{
232 // The number of pixels that are show horizontally.
235 // The number of pixels that are shown vertically.
238 // The number of *pixels* that a line in the buffer takes in
239 // memory. This may be >= width.
242 // The format of the buffer. One of WINDOW_FORMAT_*
249 uint32_t reserved
[6];
250 } ANativeWindow_Buffer
;
253 ANativeWindow_Buffer buffer
;
255 if (!sLibrary
->ANativeWindow_lock(mWindow
, &buffer
, nullptr)) {
256 ALOG("Failed to lock");
260 *out_bits
= buffer
.bits
;
261 *out_width
= buffer
.width
;
262 *out_height
= buffer
.height
;
263 *out_stride
= buffer
.stride
;
264 *out_format
= (AndroidWindowFormat
)buffer
.format
;
269 AndroidNativeWindow::UnlockAndPost()
272 ALOG("Not initialized");
276 return sLibrary
->ANativeWindow_unlockAndPost(mWindow
);
281 #endif // MOZ_WIDGET_ANDROID