Bumping gaia.json for 2 gaia revision(s) a=gaia-bump
[gecko.git] / gfx / gl / AndroidNativeWindow.cpp
blob967377a0ca3d6abae90587530f5eee50aa687715
1 #ifdef MOZ_WIDGET_ANDROID
3 #include "AndroidNativeWindow.h"
4 #include "prlink.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)
10 #else
11 #define ALOG(args...) ((void)0)
12 #endif
14 using namespace mozilla::gfx;
15 using namespace mozilla::gl;
16 using namespace mozilla;
18 class NativeWindowLibrary
20 public:
22 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);
46 if (!Initialized()) {
47 return nullptr;
50 return fANativeWindow_fromSurface(aEnv, aSurface);
53 void ANativeWindow_release(void* aWindow) {
54 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__, aWindow);
55 if (!Initialized()) {
56 return;
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);
64 if (!Initialized()) {
65 return nullptr;
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);
74 if (!Initialized()) {
75 return false;
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);
83 if (!Initialized()) {
84 return false;
87 return fANativeWindow_unlockAndPost(aWindow) == 0;
90 AndroidWindowFormat ANativeWindow_getFormat(void* aWindow) {
91 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__, aWindow);
92 if (!Initialized()) {
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()) {
102 return -1;
105 return fANativeWindow_getWidth(aWindow);
108 int32_t ANativeWindow_getHeight(void* aWindow) {
109 ALOG("%s: window=%p\n", __PRETTY_FUNCTION__, aWindow);
110 if (!Initialized()) {
111 return -1;
114 return fANativeWindow_getHeight(aWindow);
117 bool Initialized() {
118 return fANativeWindow_fromSurface && fANativeWindow_release && fANativeWindow_setBuffersGeometry
119 && fANativeWindow_lock && fANativeWindow_unlockAndPost && fANativeWindow_getFormat && fANativeWindow_getWidth
120 && fANativeWindow_getHeight;
123 private:
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;
152 static bool
153 EnsureInit()
155 static bool initialized = false;
156 if (!initialized) {
157 if (!sLibrary) {
158 sLibrary = new NativeWindowLibrary();
160 initialized = sLibrary->Initialized();
163 return initialized;
167 namespace mozilla {
169 /* static */ AndroidNativeWindow*
170 AndroidNativeWindow::CreateFromSurface(JNIEnv* aEnv, jobject aSurface)
172 if (!EnsureInit()) {
173 ALOG("Not initialized");
174 return nullptr;
177 void* window = sLibrary->ANativeWindow_fromSurface(aEnv, aSurface);
178 if (!window) {
179 ALOG("Failed to create window from surface");
180 return nullptr;
183 return new AndroidNativeWindow(window);
186 AndroidNativeWindow::~AndroidNativeWindow()
188 if (EnsureInit() && mWindow) {
189 sLibrary->ANativeWindow_release(mWindow);
190 mWindow = nullptr;
194 IntSize
195 AndroidNativeWindow::Size()
197 MOZ_ASSERT(mWindow);
198 if (!EnsureInit()) {
199 return IntSize(0, 0);
202 return IntSize(sLibrary->ANativeWindow_getWidth(mWindow), sLibrary->ANativeWindow_getHeight(mWindow));
205 AndroidWindowFormat
206 AndroidNativeWindow::Format()
208 MOZ_ASSERT(mWindow);
209 if (!EnsureInit()) {
210 return AndroidWindowFormat::Unknown;
213 return sLibrary->ANativeWindow_getFormat(mWindow);
216 bool
217 AndroidNativeWindow::SetBuffersGeometry(int32_t aWidth, int32_t aHeight, AndroidWindowFormat aFormat)
219 MOZ_ASSERT(mWindow);
220 if (!EnsureInit())
221 return false;
223 return sLibrary->ANativeWindow_setBuffersGeometry(mWindow, aWidth, aHeight, (int32_t)aFormat);
226 bool
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.
233 int32_t width;
235 // The number of pixels that are shown vertically.
236 int32_t height;
238 // The number of *pixels* that a line in the buffer takes in
239 // memory. This may be >= width.
240 int32_t stride;
242 // The format of the buffer. One of WINDOW_FORMAT_*
243 int32_t format;
245 // The actual bits.
246 void* bits;
248 // Do not touch.
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");
257 return false;
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;
265 return true;
268 bool
269 AndroidNativeWindow::UnlockAndPost()
271 if (!EnsureInit()) {
272 ALOG("Not initialized");
273 return false;
276 return sLibrary->ANativeWindow_unlockAndPost(mWindow);
281 #endif // MOZ_WIDGET_ANDROID