mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 686992 - Draw to Android window/surface directly r=blassey
This commit is contained in:
parent
f44def4369
commit
baeb34d321
@ -248,75 +248,65 @@ class GeckoSurfaceView
|
|||||||
|
|
||||||
mSurfaceLock.lock();
|
mSurfaceLock.lock();
|
||||||
|
|
||||||
|
if (mInDrawing) {
|
||||||
|
Log.w(LOG_FILE_NAME, "surfaceChanged while mInDrawing is true!");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean invalidSize;
|
||||||
|
|
||||||
|
if (width == 0 || height == 0) {
|
||||||
|
mSoftwareBitmap = null;
|
||||||
|
mSoftwareBuffer = null;
|
||||||
|
mSoftwareBufferCopy = null;
|
||||||
|
invalidSize = true;
|
||||||
|
} else {
|
||||||
|
invalidSize = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean doSyncDraw =
|
||||||
|
mDrawMode == DRAW_2D &&
|
||||||
|
!invalidSize &&
|
||||||
|
GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning);
|
||||||
|
mSyncDraw = doSyncDraw;
|
||||||
|
|
||||||
|
mFormat = format;
|
||||||
|
mWidth = width;
|
||||||
|
mHeight = height;
|
||||||
|
mSurfaceValid = true;
|
||||||
|
|
||||||
|
Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (mInDrawing) {
|
|
||||||
Log.w(LOG_FILE_NAME, "surfaceChanged while mInDrawing is true!");
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean invalidSize;
|
|
||||||
|
|
||||||
if (width == 0 || height == 0) {
|
|
||||||
mSoftwareBitmap = null;
|
|
||||||
mSoftwareBuffer = null;
|
|
||||||
mSoftwareBufferCopy = null;
|
|
||||||
invalidSize = true;
|
|
||||||
} else {
|
|
||||||
invalidSize = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean doSyncDraw =
|
|
||||||
mDrawMode == DRAW_2D &&
|
|
||||||
!invalidSize &&
|
|
||||||
GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning);
|
|
||||||
mSyncDraw = doSyncDraw;
|
|
||||||
|
|
||||||
mFormat = format;
|
|
||||||
mWidth = width;
|
|
||||||
mHeight = height;
|
|
||||||
mSurfaceValid = true;
|
|
||||||
|
|
||||||
Log.i(LOG_FILE_NAME, "surfaceChanged: fmt: " + format + " dim: " + width + " " + height);
|
|
||||||
|
|
||||||
DisplayMetrics metrics = new DisplayMetrics();
|
DisplayMetrics metrics = new DisplayMetrics();
|
||||||
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||||
|
|
||||||
GeckoEvent e = new GeckoEvent(GeckoEvent.SIZE_CHANGED, width, height,
|
GeckoEvent e = new GeckoEvent(GeckoEvent.SIZE_CHANGED, width, height,
|
||||||
metrics.widthPixels, metrics.heightPixels);
|
metrics.widthPixels, metrics.heightPixels);
|
||||||
GeckoAppShell.sendEventToGecko(e);
|
GeckoAppShell.sendEventToGecko(e);
|
||||||
|
|
||||||
if (!doSyncDraw) {
|
|
||||||
if (mDrawMode == DRAW_GLES_2 || mShowingSplashScreen)
|
|
||||||
return;
|
|
||||||
Canvas c = holder.lockCanvas();
|
|
||||||
c.drawARGB(255, 255, 255, 255);
|
|
||||||
holder.unlockCanvasAndPost(c);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
GeckoAppShell.scheduleRedraw();
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
mSurfaceLock.unlock();
|
mSurfaceLock.unlock();
|
||||||
if (mDrawMode == DRAW_GLES_2) {
|
|
||||||
// Force a frame to be drawn before the surfaceChange returns,
|
|
||||||
// otherwise we get artifacts.
|
|
||||||
GeckoAppShell.scheduleRedraw();
|
|
||||||
GeckoAppShell.geckoEventSync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object syncDrawObject = null;
|
if (doSyncDraw) {
|
||||||
try {
|
Object syncDrawObject = null;
|
||||||
syncDrawObject = mSyncDraws.take();
|
try {
|
||||||
} catch (InterruptedException ie) {
|
syncDrawObject = mSyncDraws.take();
|
||||||
Log.e(LOG_FILE_NAME, "Threw exception while getting sync draw bitmap/buffer: ", ie);
|
} catch (InterruptedException ie) {
|
||||||
}
|
Log.e(LOG_FILE_NAME, "Threw exception while getting sync draw bitmap/buffer: ", ie);
|
||||||
if (syncDrawObject != null) {
|
}
|
||||||
if (syncDrawObject instanceof Bitmap)
|
if (syncDrawObject != null) {
|
||||||
draw(holder, (Bitmap)syncDrawObject);
|
if (syncDrawObject instanceof Bitmap)
|
||||||
else
|
draw(holder, (Bitmap)syncDrawObject);
|
||||||
draw(holder, (ByteBuffer)syncDrawObject);
|
else
|
||||||
} else {
|
draw(holder, (ByteBuffer)syncDrawObject);
|
||||||
Log.e("GeckoSurfaceViewJava", "Synchronised draw object is null");
|
} else {
|
||||||
|
Log.e("GeckoSurfaceViewJava", "Synchronised draw object is null");
|
||||||
|
}
|
||||||
|
} else if (!mShowingSplashScreen) {
|
||||||
|
// Make sure a frame is drawn before we return
|
||||||
|
// otherwise we see artifacts or a black screen
|
||||||
|
GeckoAppShell.scheduleRedraw();
|
||||||
|
GeckoAppShell.geckoEventSync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,6 +362,10 @@ class GeckoSurfaceView
|
|||||||
return mSoftwareBuffer;
|
return mSoftwareBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Surface getSurface() {
|
||||||
|
return getHolder().getSurface();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called on Gecko thread
|
* Called on Gecko thread
|
||||||
*/
|
*/
|
||||||
|
@ -106,8 +106,9 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
|||||||
|
|
||||||
mJNIEnv = nsnull;
|
mJNIEnv = nsnull;
|
||||||
mThread = nsnull;
|
mThread = nsnull;
|
||||||
mOpenedBitmapLibrary = false;
|
mOpenedGraphicsLibraries = false;
|
||||||
mHasNativeBitmapAccess = false;
|
mHasNativeBitmapAccess = false;
|
||||||
|
mHasNativeWindowAccess = false;
|
||||||
|
|
||||||
mGeckoAppShellClass = (jclass) jEnv->NewGlobalRef(jGeckoAppShellClass);
|
mGeckoAppShellClass = (jclass) jEnv->NewGlobalRef(jGeckoAppShellClass);
|
||||||
|
|
||||||
@ -977,33 +978,46 @@ AndroidBridge::ExecuteNextRunnable()
|
|||||||
}
|
}
|
||||||
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "leaving %s", __PRETTY_FUNCTION__);
|
__android_log_print(ANDROID_LOG_INFO, "GeckoBridge", "leaving %s", __PRETTY_FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AndroidBridge::OpenGraphicsLibraries()
|
||||||
|
{
|
||||||
|
if (!mOpenedGraphicsLibraries) {
|
||||||
|
// Try to dlopen libjnigraphics.so for direct bitmap access on
|
||||||
|
// Android 2.2+ (API level 8)
|
||||||
|
mOpenedGraphicsLibraries = true;
|
||||||
|
|
||||||
|
void *handle = dlopen("/system/lib/libjnigraphics.so", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (handle) {
|
||||||
|
AndroidBitmap_getInfo = (int (*)(JNIEnv *, jobject, void *))dlsym(handle, "AndroidBitmap_getInfo");
|
||||||
|
AndroidBitmap_lockPixels = (int (*)(JNIEnv *, jobject, void **))dlsym(handle, "AndroidBitmap_lockPixels");
|
||||||
|
AndroidBitmap_unlockPixels = (int (*)(JNIEnv *, jobject))dlsym(handle, "AndroidBitmap_unlockPixels");
|
||||||
|
|
||||||
|
ALOG_BRIDGE("Successfully opened libjnigraphics.so");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to dlopen libandroid.so for and native window access on
|
||||||
|
// Android 2.3+ (API level 9)
|
||||||
|
handle = dlopen("/system/lib/libandroid.so", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (handle) {
|
||||||
|
ANativeWindow_fromSurface = (void* (*)(JNIEnv*, jobject))dlsym(handle, "ANativeWindow_fromSurface");
|
||||||
|
ANativeWindow_release = (void (*)(void*))dlsym(handle, "ANativeWindow_release");
|
||||||
|
ANativeWindow_setBuffersGeometry = (int (*)(void*, int, int, int)) dlsym(handle, "ANativeWindow_setBuffersGeometry");
|
||||||
|
ANativeWindow_lock = (int (*)(void*, void*, void*)) dlsym(handle, "ANativeWindow_lock");
|
||||||
|
ANativeWindow_unlockAndPost = (int (*)(void*))dlsym(handle, "ANativeWindow_unlockAndPost");
|
||||||
|
|
||||||
|
ALOG_BRIDGE("Successfully opened libandroid.so");
|
||||||
|
}
|
||||||
|
|
||||||
|
mHasNativeBitmapAccess = AndroidBitmap_getInfo && AndroidBitmap_lockPixels && AndroidBitmap_unlockPixels;
|
||||||
|
mHasNativeWindowAccess = ANativeWindow_fromSurface && ANativeWindow_release && ANativeWindow_lock && ANativeWindow_unlockAndPost;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AndroidBridge::HasNativeBitmapAccess()
|
AndroidBridge::HasNativeBitmapAccess()
|
||||||
{
|
{
|
||||||
if (!mOpenedBitmapLibrary) {
|
OpenGraphicsLibraries();
|
||||||
// Try to dlopen libjnigraphics.so for direct bitmap access on
|
|
||||||
// Android 2.2+ (API level 8)
|
|
||||||
mOpenedBitmapLibrary = true;
|
|
||||||
|
|
||||||
void *handle = dlopen("/system/lib/libjnigraphics.so", RTLD_LAZY | RTLD_LOCAL);
|
|
||||||
if (handle == nsnull)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
AndroidBitmap_getInfo = (int (*)(JNIEnv *, jobject, void *))dlsym(handle, "AndroidBitmap_getInfo");
|
|
||||||
if (AndroidBitmap_getInfo == nsnull)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
AndroidBitmap_lockPixels = (int (*)(JNIEnv *, jobject, void **))dlsym(handle, "AndroidBitmap_lockPixels");
|
|
||||||
if (AndroidBitmap_lockPixels == nsnull)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
AndroidBitmap_unlockPixels = (int (*)(JNIEnv *, jobject))dlsym(handle, "AndroidBitmap_unlockPixels");
|
|
||||||
if (AndroidBitmap_unlockPixels == nsnull)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ALOG_BRIDGE("Successfully opened libjnigraphics.so");
|
|
||||||
mHasNativeBitmapAccess = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return mHasNativeBitmapAccess;
|
return mHasNativeBitmapAccess;
|
||||||
}
|
}
|
||||||
@ -1057,3 +1071,92 @@ AndroidBridge::UnlockBitmap(jobject bitmap)
|
|||||||
if ((err = AndroidBitmap_unlockPixels(JNI(), bitmap)) != 0)
|
if ((err = AndroidBitmap_unlockPixels(JNI(), bitmap)) != 0)
|
||||||
ALOG_BRIDGE("AndroidBitmap_unlockPixels failed! (error %d)", err);
|
ALOG_BRIDGE("AndroidBitmap_unlockPixels failed! (error %d)", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
AndroidBridge::HasNativeWindowAccess()
|
||||||
|
{
|
||||||
|
OpenGraphicsLibraries();
|
||||||
|
|
||||||
|
return mHasNativeWindowAccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
AndroidBridge::AcquireNativeWindow(jobject surface)
|
||||||
|
{
|
||||||
|
if (!HasNativeWindowAccess())
|
||||||
|
return nsnull;
|
||||||
|
|
||||||
|
return ANativeWindow_fromSurface(JNI(), surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
AndroidBridge::ReleaseNativeWindow(void *window)
|
||||||
|
{
|
||||||
|
if (!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ANativeWindow_release(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AndroidBridge::SetNativeWindowFormat(void *window, int format)
|
||||||
|
{
|
||||||
|
return ANativeWindow_setBuffersGeometry(window, 0, 0, format) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AndroidBridge::LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride)
|
||||||
|
{
|
||||||
|
/* Copied from native_window.h in Android NDK (platform-9) */
|
||||||
|
typedef struct ANativeWindow_Buffer {
|
||||||
|
// The number of pixels that are show horizontally.
|
||||||
|
int32_t width;
|
||||||
|
|
||||||
|
// The number of pixels that are shown vertically.
|
||||||
|
int32_t height;
|
||||||
|
|
||||||
|
// The number of *pixels* that a line in the buffer takes in
|
||||||
|
// memory. This may be >= width.
|
||||||
|
int32_t stride;
|
||||||
|
|
||||||
|
// The format of the buffer. One of WINDOW_FORMAT_*
|
||||||
|
int32_t format;
|
||||||
|
|
||||||
|
// The actual bits.
|
||||||
|
void* bits;
|
||||||
|
|
||||||
|
// Do not touch.
|
||||||
|
uint32_t reserved[6];
|
||||||
|
} ANativeWindow_Buffer;
|
||||||
|
|
||||||
|
int err;
|
||||||
|
ANativeWindow_Buffer buffer;
|
||||||
|
|
||||||
|
*bits = NULL;
|
||||||
|
*width = *height = *format = 0;
|
||||||
|
if ((err = ANativeWindow_lock(window, (void*)&buffer, NULL)) != 0) {
|
||||||
|
ALOG_BRIDGE("ANativeWindow_lock failed! (error %d)", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*bits = (unsigned char*)buffer.bits;
|
||||||
|
*width = buffer.width;
|
||||||
|
*height = buffer.height;
|
||||||
|
*format = buffer.format;
|
||||||
|
*stride = buffer.stride;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
AndroidBridge::UnlockWindow(void* window)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
if ((err = ANativeWindow_unlockAndPost(window)) != 0) {
|
||||||
|
ALOG_BRIDGE("ANativeWindow_unlockAndPost failed! (error %d)", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -267,6 +267,22 @@ public:
|
|||||||
|
|
||||||
void ExecuteNextRunnable();
|
void ExecuteNextRunnable();
|
||||||
|
|
||||||
|
/* Copied from Android's native_window.h in newer (platform 9) NDK */
|
||||||
|
enum {
|
||||||
|
WINDOW_FORMAT_RGBA_8888 = 1,
|
||||||
|
WINDOW_FORMAT_RGBX_8888 = 2,
|
||||||
|
WINDOW_FORMAT_RGB_565 = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool HasNativeWindowAccess();
|
||||||
|
|
||||||
|
void *AcquireNativeWindow(jobject surface);
|
||||||
|
void ReleaseNativeWindow(void *window);
|
||||||
|
bool SetNativeWindowFormat(void *window, int format);
|
||||||
|
|
||||||
|
bool LockWindow(void *window, unsigned char **bits, int *width, int *height, int *format, int *stride);
|
||||||
|
bool UnlockWindow(void *window);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static AndroidBridge *sBridge;
|
static AndroidBridge *sBridge;
|
||||||
|
|
||||||
@ -288,8 +304,11 @@ protected:
|
|||||||
|
|
||||||
void EnsureJNIThread();
|
void EnsureJNIThread();
|
||||||
|
|
||||||
bool mOpenedBitmapLibrary;
|
bool mOpenedGraphicsLibraries;
|
||||||
|
void OpenGraphicsLibraries();
|
||||||
|
|
||||||
bool mHasNativeBitmapAccess;
|
bool mHasNativeBitmapAccess;
|
||||||
|
bool mHasNativeWindowAccess;
|
||||||
|
|
||||||
nsCOMArray<nsIRunnable> mRunnableQueue;
|
nsCOMArray<nsIRunnable> mRunnableQueue;
|
||||||
|
|
||||||
@ -346,6 +365,13 @@ protected:
|
|||||||
int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
|
int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
|
||||||
int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
|
int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
|
||||||
int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
|
int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
|
||||||
|
|
||||||
|
void* (*ANativeWindow_fromSurface)(JNIEnv *env, jobject surface);
|
||||||
|
void (*ANativeWindow_release)(void *window);
|
||||||
|
int (*ANativeWindow_setBuffersGeometry)(void *window, int width, int height, int format);
|
||||||
|
|
||||||
|
int (* ANativeWindow_lock)(void *window, void *outBuffer, void *inOutDirtyBounds);
|
||||||
|
int (* ANativeWindow_unlockAndPost)(void *window);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,7 @@ jmethodID AndroidGeckoSurfaceView::jDraw2DBitmapMethod = 0;
|
|||||||
jmethodID AndroidGeckoSurfaceView::jDraw2DBufferMethod = 0;
|
jmethodID AndroidGeckoSurfaceView::jDraw2DBufferMethod = 0;
|
||||||
jmethodID AndroidGeckoSurfaceView::jGetSoftwareDrawBitmapMethod = 0;
|
jmethodID AndroidGeckoSurfaceView::jGetSoftwareDrawBitmapMethod = 0;
|
||||||
jmethodID AndroidGeckoSurfaceView::jGetSoftwareDrawBufferMethod = 0;
|
jmethodID AndroidGeckoSurfaceView::jGetSoftwareDrawBufferMethod = 0;
|
||||||
|
jmethodID AndroidGeckoSurfaceView::jGetSurfaceMethod = 0;
|
||||||
jmethodID AndroidGeckoSurfaceView::jGetHolderMethod = 0;
|
jmethodID AndroidGeckoSurfaceView::jGetHolderMethod = 0;
|
||||||
|
|
||||||
#define JNI() (AndroidBridge::JNI())
|
#define JNI() (AndroidBridge::JNI())
|
||||||
@ -183,6 +184,7 @@ AndroidGeckoSurfaceView::InitGeckoSurfaceViewClass(JNIEnv *jEnv)
|
|||||||
jEndDrawingMethod = getMethod("endDrawing", "()V");
|
jEndDrawingMethod = getMethod("endDrawing", "()V");
|
||||||
jDraw2DBitmapMethod = getMethod("draw2D", "(Landroid/graphics/Bitmap;II)V");
|
jDraw2DBitmapMethod = getMethod("draw2D", "(Landroid/graphics/Bitmap;II)V");
|
||||||
jDraw2DBufferMethod = getMethod("draw2D", "(Ljava/nio/ByteBuffer;I)V");
|
jDraw2DBufferMethod = getMethod("draw2D", "(Ljava/nio/ByteBuffer;I)V");
|
||||||
|
jGetSurfaceMethod = getMethod("getSurface", "()Landroid/view/Surface;");
|
||||||
jGetHolderMethod = getMethod("getHolder", "()Landroid/view/SurfaceHolder;");
|
jGetHolderMethod = getMethod("getHolder", "()Landroid/view/SurfaceHolder;");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,6 +518,12 @@ AndroidGeckoSurfaceView::GetSoftwareDrawBuffer()
|
|||||||
return JNI()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod);
|
return JNI()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBufferMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jobject
|
||||||
|
AndroidGeckoSurfaceView::GetSurface()
|
||||||
|
{
|
||||||
|
return JNI()->CallObjectMethod(wrapped_obj, jGetSurfaceMethod);
|
||||||
|
}
|
||||||
|
|
||||||
jobject
|
jobject
|
||||||
AndroidGeckoSurfaceView::GetSurfaceHolder()
|
AndroidGeckoSurfaceView::GetSurfaceHolder()
|
||||||
{
|
{
|
||||||
|
@ -175,6 +175,8 @@ public:
|
|||||||
void Draw2D(jobject bitmap, int width, int height);
|
void Draw2D(jobject bitmap, int width, int height);
|
||||||
void Draw2D(jobject buffer, int stride);
|
void Draw2D(jobject buffer, int stride);
|
||||||
|
|
||||||
|
jobject GetSurface();
|
||||||
|
|
||||||
// must have a JNI local frame when calling this,
|
// must have a JNI local frame when calling this,
|
||||||
// and you'd better know what you're doing
|
// and you'd better know what you're doing
|
||||||
jobject GetSurfaceHolder();
|
jobject GetSurfaceHolder();
|
||||||
@ -187,6 +189,7 @@ protected:
|
|||||||
static jmethodID jDraw2DBufferMethod;
|
static jmethodID jDraw2DBufferMethod;
|
||||||
static jmethodID jGetSoftwareDrawBitmapMethod;
|
static jmethodID jGetSoftwareDrawBitmapMethod;
|
||||||
static jmethodID jGetSoftwareDrawBufferMethod;
|
static jmethodID jGetSoftwareDrawBufferMethod;
|
||||||
|
static jmethodID jGetSurfaceMethod;
|
||||||
static jmethodID jGetHolderMethod;
|
static jmethodID jGetHolderMethod;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +129,7 @@ static nsRefPtr<gl::GLContext> sGLContext;
|
|||||||
static bool sFailedToCreateGLContext = false;
|
static bool sFailedToCreateGLContext = false;
|
||||||
static bool sValidSurface;
|
static bool sValidSurface;
|
||||||
static bool sSurfaceExists = false;
|
static bool sSurfaceExists = false;
|
||||||
|
static void *sNativeWindow = nsnull;
|
||||||
|
|
||||||
// Multitouch swipe thresholds in inches
|
// Multitouch swipe thresholds in inches
|
||||||
static const double SWIPE_MAX_PINCH_DELTA_INCHES = 0.4;
|
static const double SWIPE_MAX_PINCH_DELTA_INCHES = 0.4;
|
||||||
@ -846,12 +847,27 @@ nsWindow::OnGlobalAndroidEvent(AndroidGeckoEvent *ae)
|
|||||||
|
|
||||||
case AndroidGeckoEvent::SURFACE_CREATED:
|
case AndroidGeckoEvent::SURFACE_CREATED:
|
||||||
sSurfaceExists = true;
|
sSurfaceExists = true;
|
||||||
|
|
||||||
|
if (AndroidBridge::Bridge()->HasNativeWindowAccess()) {
|
||||||
|
AndroidGeckoSurfaceView& sview(AndroidBridge::Bridge()->SurfaceView());
|
||||||
|
jobject surface = sview.GetSurface();
|
||||||
|
if (surface) {
|
||||||
|
sNativeWindow = AndroidBridge::Bridge()->AcquireNativeWindow(surface);
|
||||||
|
if (sNativeWindow) {
|
||||||
|
AndroidBridge::Bridge()->SetNativeWindowFormat(sNativeWindow, AndroidBridge::WINDOW_FORMAT_RGB_565);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AndroidGeckoEvent::SURFACE_DESTROYED:
|
case AndroidGeckoEvent::SURFACE_DESTROYED:
|
||||||
if (sGLContext && sValidSurface) {
|
if (sGLContext && sValidSurface) {
|
||||||
sGLContext->ReleaseSurface();
|
sGLContext->ReleaseSurface();
|
||||||
}
|
}
|
||||||
|
if (sNativeWindow) {
|
||||||
|
AndroidBridge::Bridge()->ReleaseNativeWindow(sNativeWindow);
|
||||||
|
sNativeWindow = nsnull;
|
||||||
|
}
|
||||||
sSurfaceExists = false;
|
sSurfaceExists = false;
|
||||||
sValidSurface = false;
|
sValidSurface = false;
|
||||||
break;
|
break;
|
||||||
@ -1002,7 +1018,35 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
|
|||||||
AndroidBridge::Bridge()->HideProgressDialogOnce();
|
AndroidBridge::Bridge()->HideProgressDialogOnce();
|
||||||
|
|
||||||
if (GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_BASIC) {
|
if (GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_BASIC) {
|
||||||
if (AndroidBridge::Bridge()->HasNativeBitmapAccess()) {
|
if (sNativeWindow) {
|
||||||
|
unsigned char *bits;
|
||||||
|
int width, height, format, stride;
|
||||||
|
if (!AndroidBridge::Bridge()->LockWindow(sNativeWindow, &bits, &width, &height, &format, &stride)) {
|
||||||
|
ALOG("failed to lock buffer - skipping draw");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bits || format != AndroidBridge::WINDOW_FORMAT_RGB_565 ||
|
||||||
|
width != mBounds.width || height != mBounds.height) {
|
||||||
|
|
||||||
|
ALOG("surface is not expected dimensions or format - skipping draw");
|
||||||
|
AndroidBridge::Bridge()->UnlockWindow(sNativeWindow);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsRefPtr<gfxImageSurface> targetSurface =
|
||||||
|
new gfxImageSurface(bits,
|
||||||
|
gfxIntSize(mBounds.width, mBounds.height),
|
||||||
|
stride * 2,
|
||||||
|
gfxASurface::ImageFormatRGB16_565);
|
||||||
|
if (targetSurface->CairoStatus()) {
|
||||||
|
ALOG("### Failed to create a valid surface from the bitmap");
|
||||||
|
} else {
|
||||||
|
DrawTo(targetSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
AndroidBridge::Bridge()->UnlockWindow(sNativeWindow);
|
||||||
|
} else if (AndroidBridge::Bridge()->HasNativeBitmapAccess()) {
|
||||||
jobject bitmap = sview.GetSoftwareDrawBitmap();
|
jobject bitmap = sview.GetSoftwareDrawBitmap();
|
||||||
if (!bitmap) {
|
if (!bitmap) {
|
||||||
ALOG("no bitmap to draw into - skipping draw");
|
ALOG("no bitmap to draw into - skipping draw");
|
||||||
|
Loading…
Reference in New Issue
Block a user