mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
Bug 692198 - Make Flash on Android draw to bitmap intead of SurfaceView directly r=blassey
commit 872c1f5bf1f2c205c3f999409ed55f31627c968a Author: James Willcox <jwillcox@mozilla.com> Bug 692198 - Make Flash on Android draw to bitmap intead of SurfaceView directly
This commit is contained in:
parent
f77b6f4147
commit
ae1884f3a8
@ -42,6 +42,7 @@
|
||||
#include "AndroidBridge.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "gfxContext.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
|
||||
#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "GeckoPlugins" , ## args)
|
||||
#define ASSIGN(obj, name) (obj)->name = anp_surface_##name
|
||||
@ -51,17 +52,11 @@
|
||||
static struct ANPSurfaceInterfaceJavaGlue {
|
||||
bool initialized;
|
||||
jclass geckoAppShellClass;
|
||||
jclass lockInfoCls;
|
||||
jmethodID lockSurfaceANP;
|
||||
jmethodID jUnlockSurfaceANP;
|
||||
jfieldID jDirtyTop;
|
||||
jfieldID jDirtyLeft;
|
||||
jfieldID jDirtyBottom;
|
||||
jfieldID jDirtyRight;
|
||||
jclass surfaceInfoCls;
|
||||
jmethodID getSurfaceInfo;
|
||||
jfieldID jFormat;
|
||||
jfieldID jWidth ;
|
||||
jfieldID jHeight;
|
||||
jfieldID jBuffer;
|
||||
} gSurfaceJavaGlue;
|
||||
|
||||
#define getClassGlobalRef(env, cname) \
|
||||
@ -74,23 +69,16 @@ static void init(JNIEnv* env) {
|
||||
gSurfaceJavaGlue.geckoAppShellClass = mozilla::AndroidBridge::GetGeckoAppShellClass();
|
||||
|
||||
jmethodID getClass = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass,
|
||||
"getSurfaceLockInfoClass",
|
||||
"getSurfaceInfoClass",
|
||||
"()Ljava/lang/Class;");
|
||||
|
||||
gSurfaceJavaGlue.lockInfoCls = (jclass) env->NewGlobalRef(env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass, getClass));
|
||||
gSurfaceJavaGlue.surfaceInfoCls = (jclass) env->NewGlobalRef(env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass, getClass));
|
||||
|
||||
gSurfaceJavaGlue.jDirtyTop = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyTop", "I");
|
||||
gSurfaceJavaGlue.jDirtyLeft = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyLeft", "I");
|
||||
gSurfaceJavaGlue.jDirtyBottom = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyBottom", "I");
|
||||
gSurfaceJavaGlue.jDirtyRight = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "dirtyRight", "I");
|
||||
gSurfaceJavaGlue.jFormat = env->GetFieldID(gSurfaceJavaGlue.surfaceInfoCls, "format", "I");
|
||||
gSurfaceJavaGlue.jWidth = env->GetFieldID(gSurfaceJavaGlue.surfaceInfoCls, "width", "I");
|
||||
gSurfaceJavaGlue.jHeight = env->GetFieldID(gSurfaceJavaGlue.surfaceInfoCls, "height", "I");
|
||||
|
||||
gSurfaceJavaGlue.jFormat = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "format", "I");
|
||||
gSurfaceJavaGlue.jWidth = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "width", "I");
|
||||
gSurfaceJavaGlue.jHeight = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "height", "I");
|
||||
|
||||
gSurfaceJavaGlue.jBuffer = env->GetFieldID(gSurfaceJavaGlue.lockInfoCls, "buffer", "Ljava/nio/Buffer;");
|
||||
gSurfaceJavaGlue.lockSurfaceANP = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "lockSurfaceANP", "(Landroid/view/SurfaceView;IIII)Lorg/mozilla/gecko/SurfaceLockInfo;");
|
||||
gSurfaceJavaGlue.jUnlockSurfaceANP = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "unlockSurfaceANP", "(Landroid/view/SurfaceView;)V");
|
||||
gSurfaceJavaGlue.getSurfaceInfo = env->GetStaticMethodID(gSurfaceJavaGlue.geckoAppShellClass, "getSurfaceInfo", "(Landroid/view/SurfaceView;)Lorg/mozilla/gecko/SurfaceInfo;");
|
||||
gSurfaceJavaGlue.initialized = true;
|
||||
}
|
||||
|
||||
@ -103,62 +91,62 @@ static bool anp_lock(JNIEnv* env, jobject surfaceView, ANPBitmap* bitmap, ANPRec
|
||||
|
||||
init(env);
|
||||
|
||||
jvalue args[5];
|
||||
args[0].l = surfaceView;
|
||||
if (dirtyRect) {
|
||||
args[1].i = dirtyRect->top;
|
||||
args[2].i = dirtyRect->left;
|
||||
args[3].i = dirtyRect->bottom;
|
||||
args[4].i = dirtyRect->right;
|
||||
LOG("dirty rect: %d, %d, %d, %d", dirtyRect->top, dirtyRect->left, dirtyRect->bottom, dirtyRect->right);
|
||||
} else {
|
||||
args[1].i = args[2].i = args[3].i = args[4].i = 0;
|
||||
}
|
||||
|
||||
jobject info = env->CallStaticObjectMethod(gSurfaceJavaGlue.geckoAppShellClass,
|
||||
gSurfaceJavaGlue.lockSurfaceANP,
|
||||
surfaceView, args[1].i, args[2].i, args[3].i, args[4].i);
|
||||
gSurfaceJavaGlue.getSurfaceInfo, surfaceView);
|
||||
|
||||
LOG("info: %p", info);
|
||||
if (!info)
|
||||
return false;
|
||||
|
||||
// the surface may have expanded the dirty region so we must to pass that
|
||||
// information back to the plugin.
|
||||
if (dirtyRect) {
|
||||
dirtyRect->left = env->GetIntField(info, gSurfaceJavaGlue.jDirtyLeft);
|
||||
dirtyRect->right = env->GetIntField(info, gSurfaceJavaGlue.jDirtyRight);
|
||||
dirtyRect->top = env->GetIntField(info, gSurfaceJavaGlue.jDirtyTop);
|
||||
dirtyRect->bottom = env->GetIntField(info, gSurfaceJavaGlue.jDirtyBottom);
|
||||
LOG("dirty rect: %d, %d, %d, %d", dirtyRect->top, dirtyRect->left, dirtyRect->bottom, dirtyRect->right);
|
||||
}
|
||||
|
||||
bitmap->width = env->GetIntField(info, gSurfaceJavaGlue.jWidth);
|
||||
bitmap->height = env->GetIntField(info, gSurfaceJavaGlue.jHeight);
|
||||
|
||||
if (bitmap->width <= 0 || bitmap->height <= 0)
|
||||
return false;
|
||||
|
||||
int format = env->GetIntField(info, gSurfaceJavaGlue.jFormat);
|
||||
gfxImageFormat targetFormat;
|
||||
|
||||
// format is PixelFormat
|
||||
if (format & 0x00000001) {
|
||||
bitmap->format = kRGBA_8888_ANPBitmapFormat;
|
||||
bitmap->rowBytes = bitmap->width * 4;
|
||||
}
|
||||
else if (format & 0x00000004) {
|
||||
// We actually can't handle this right now because gfxImageSurface
|
||||
// doesn't support RGBA32.
|
||||
LOG("Unable to handle 32bit pixel format");
|
||||
return false;
|
||||
} else if (format & 0x00000004) {
|
||||
bitmap->format = kRGB_565_ANPBitmapFormat;
|
||||
bitmap->rowBytes = bitmap->width * 2;
|
||||
}
|
||||
else {
|
||||
targetFormat = gfxASurface::ImageFormatRGB16_565;
|
||||
} else {
|
||||
LOG("format from glue is unknown %d\n", format);
|
||||
return false;
|
||||
}
|
||||
|
||||
jobject buf = env->GetObjectField(info, gSurfaceJavaGlue.jBuffer);
|
||||
bitmap->baseAddr = env->GetDirectBufferAddress(buf);
|
||||
nsNPAPIPluginInstance* pinst = nsNPAPIPluginInstance::FindByJavaSurface((void*)surfaceView);
|
||||
if (!pinst) {
|
||||
LOG("Failed to get plugin instance");
|
||||
return false;
|
||||
}
|
||||
|
||||
NPRect lockRect;
|
||||
if (dirtyRect) {
|
||||
lockRect.top = dirtyRect->top;
|
||||
lockRect.left = dirtyRect->left;
|
||||
lockRect.right = dirtyRect->right;
|
||||
lockRect.bottom = dirtyRect->bottom;
|
||||
} else {
|
||||
// No dirty rect, use the whole bitmap
|
||||
lockRect.top = lockRect.left = 0;
|
||||
lockRect.right = bitmap->width;
|
||||
lockRect.bottom = bitmap->height;
|
||||
}
|
||||
|
||||
LOG("format: %d, width: %d, height: %d", bitmap->format, bitmap->width, bitmap->height);
|
||||
gfxImageSurface* target = pinst->LockTargetSurface(bitmap->width, bitmap->height, targetFormat, &lockRect);
|
||||
bitmap->baseAddr = target->Data();
|
||||
|
||||
env->DeleteLocalRef(info);
|
||||
env->DeleteLocalRef(buf);
|
||||
return ( bitmap->width > 0 && bitmap->height > 0 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void anp_unlock(JNIEnv* env, jobject surfaceView) {
|
||||
@ -169,10 +157,13 @@ static void anp_unlock(JNIEnv* env, jobject surfaceView) {
|
||||
return;
|
||||
}
|
||||
|
||||
init(env);
|
||||
env->CallStaticVoidMethod(gSurfaceJavaGlue.geckoAppShellClass, gSurfaceJavaGlue.jUnlockSurfaceANP, surfaceView);
|
||||
LOG("returning from %s", __PRETTY_FUNCTION__);
|
||||
|
||||
nsNPAPIPluginInstance* pinst = nsNPAPIPluginInstance::FindByJavaSurface((void*)surfaceView);
|
||||
if (!pinst) {
|
||||
LOG("Could not find plugin instance!");
|
||||
return;
|
||||
}
|
||||
|
||||
pinst->UnlockTargetSurface(true /* invalidate the locked area */);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -65,7 +65,6 @@
|
||||
#include "ANPBase.h"
|
||||
#include <android/log.h>
|
||||
#include "android_npapi.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "AndroidBridge.h"
|
||||
#endif
|
||||
@ -73,6 +72,11 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::plugins::parent;
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <map>
|
||||
static std::map<void*, nsNPAPIPluginInstance*> sSurfaceMap;
|
||||
#endif
|
||||
|
||||
static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID);
|
||||
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
|
||||
|
||||
@ -89,6 +93,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
|
||||
#endif
|
||||
#ifdef ANDROID
|
||||
mSurface(nsnull),
|
||||
mTargetSurface(nsnull),
|
||||
mDrawingModel(0),
|
||||
#endif
|
||||
mRunning(NOT_STARTED),
|
||||
@ -122,6 +127,10 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
|
||||
mUsePluginLayersPref = useLayersPref;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
mTargetSurfaceLock = new Mutex("nsNPAPIPluginInstance::SurfaceLock");
|
||||
#endif
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
|
||||
}
|
||||
|
||||
@ -133,6 +142,22 @@ nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
|
||||
PR_Free((void *)mMIMEType);
|
||||
mMIMEType = nsnull;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
if (mSurface) {
|
||||
sSurfaceMap.erase(mSurface);
|
||||
}
|
||||
|
||||
if (mTargetSurface) {
|
||||
delete mTargetSurface;
|
||||
mTargetSurface = nsnull;
|
||||
}
|
||||
|
||||
if (mTargetSurfaceLock) {
|
||||
delete mTargetSurfaceLock;
|
||||
mTargetSurfaceLock = nsnull;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
@ -775,9 +800,61 @@ void* nsNPAPIPluginInstance::GetJavaSurface()
|
||||
|
||||
nsCOMPtr<SurfaceGetter> sg = new SurfaceGetter(mPlugin->PluginFuncs(), mNPP);
|
||||
mSurface = sg->GetSurface();
|
||||
sSurfaceMap[mSurface] = this;
|
||||
return mSurface;
|
||||
}
|
||||
|
||||
gfxImageSurface*
|
||||
nsNPAPIPluginInstance::LockTargetSurface()
|
||||
{
|
||||
mTargetSurfaceLock->Lock();
|
||||
return mTargetSurface;
|
||||
}
|
||||
|
||||
gfxImageSurface*
|
||||
nsNPAPIPluginInstance::LockTargetSurface(PRUint32 aWidth, PRUint32 aHeight, gfxImageFormat aFormat,
|
||||
NPRect* aRect)
|
||||
{
|
||||
mTargetSurfaceLock->Lock();
|
||||
if (!mTargetSurface ||
|
||||
mTargetSurface->Width() != aWidth ||
|
||||
mTargetSurface->Height() != aHeight ||
|
||||
mTargetSurface->Format() != aFormat) {
|
||||
|
||||
if (mTargetSurface) {
|
||||
delete mTargetSurface;
|
||||
}
|
||||
|
||||
mTargetSurface = new gfxImageSurface(gfxIntSize(aWidth, aHeight), aFormat);
|
||||
}
|
||||
|
||||
mTargetLockRect = *aRect;
|
||||
|
||||
return mTargetSurface;
|
||||
}
|
||||
|
||||
void
|
||||
nsNPAPIPluginInstance::InvalidateTargetRect()
|
||||
{
|
||||
InvalidateRect(&mTargetLockRect);
|
||||
}
|
||||
|
||||
void
|
||||
nsNPAPIPluginInstance::UnlockTargetSurface(bool aInvalidate)
|
||||
{
|
||||
mTargetSurfaceLock->Unlock();
|
||||
|
||||
if (aInvalidate) {
|
||||
NS_DispatchToMainThread(NS_NewRunnableMethod(this, &nsNPAPIPluginInstance::InvalidateTargetRect));
|
||||
}
|
||||
}
|
||||
|
||||
nsNPAPIPluginInstance*
|
||||
nsNPAPIPluginInstance::FindByJavaSurface(void* aJavaSurface)
|
||||
{
|
||||
return sSurfaceMap[aJavaSurface];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
nsresult nsNPAPIPluginInstance::GetDrawingModel(PRInt32* aModel)
|
||||
|
@ -50,9 +50,16 @@
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
#include "gfxASurface.h"
|
||||
#include "gfxImageSurface.h"
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/PluginLibrary.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#include "mozilla/Mutex.h"
|
||||
#endif
|
||||
|
||||
struct JSObject;
|
||||
|
||||
class nsPluginStreamListenerPeer; // browser-initiated stream class
|
||||
@ -148,6 +155,13 @@ public:
|
||||
#ifdef ANDROID
|
||||
void SetDrawingModel(PRUint32 aModel);
|
||||
void* GetJavaSurface();
|
||||
|
||||
gfxImageSurface* LockTargetSurface();
|
||||
gfxImageSurface* LockTargetSurface(PRUint32 aWidth, PRUint32 aHeight, gfxASurface::gfxImageFormat aFormat,
|
||||
NPRect* aRect);
|
||||
void UnlockTargetSurface(bool aInvalidate);
|
||||
|
||||
static nsNPAPIPluginInstance* FindByJavaSurface(void* aJavaSurface);
|
||||
#endif
|
||||
|
||||
nsresult NewStreamListener(const char* aURL, void* notifyData,
|
||||
@ -264,7 +278,12 @@ private:
|
||||
|
||||
bool mUsePluginLayersPref;
|
||||
#ifdef ANDROID
|
||||
void InvalidateTargetRect();
|
||||
|
||||
void* mSurface;
|
||||
gfxImageSurface *mTargetSurface;
|
||||
mozilla::Mutex* mTargetSurfaceLock;
|
||||
NPRect mTargetLockRect;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -1671,6 +1671,27 @@ void nsPluginInstanceOwner::ScrollPositionDidChange(nscoord aX, nscoord aY)
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
void nsPluginInstanceOwner::AddPluginView(const gfxRect& aRect)
|
||||
{
|
||||
void* javaSurface = mInstance->GetJavaSurface();
|
||||
|
||||
if (!javaSurface)
|
||||
return;
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
|
||||
jmethodID method = env->GetStaticMethodID(cls,
|
||||
"addPluginView",
|
||||
"(Landroid/view/View;DDDD)V");
|
||||
env->CallStaticVoidMethod(cls,
|
||||
method,
|
||||
javaSurface,
|
||||
aRect.x,
|
||||
aRect.y,
|
||||
aRect.width,
|
||||
aRect.height);
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::RemovePluginView()
|
||||
{
|
||||
if (mInstance && mObjectFrame) {
|
||||
@ -2812,45 +2833,6 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, HPS aHPS)
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
class AndroidPaintEventRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
AndroidPaintEventRunnable(void* aSurface, nsNPAPIPluginInstance* inst, const gfxRect& aFrameRect)
|
||||
: mSurface(aSurface), mInstance(inst), mFrameRect(aFrameRect) {
|
||||
}
|
||||
|
||||
~AndroidPaintEventRunnable() {
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
LOG("%p - AndroidPaintEventRunnable::Run\n", this);
|
||||
|
||||
if (!mInstance || !mSurface)
|
||||
return NS_OK;
|
||||
|
||||
// This needs to happen on the gecko main thread.
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
|
||||
jmethodID method = env->GetStaticMethodID(cls,
|
||||
"addPluginView",
|
||||
"(Landroid/view/View;DDDD)V");
|
||||
env->CallStaticVoidMethod(cls,
|
||||
method,
|
||||
mSurface,
|
||||
mFrameRect.x,
|
||||
mFrameRect.y,
|
||||
mFrameRect.width,
|
||||
mFrameRect.height);
|
||||
return NS_OK;
|
||||
}
|
||||
private:
|
||||
void* mSurface;
|
||||
nsCOMPtr<nsNPAPIPluginInstance> mInstance;
|
||||
gfxRect mFrameRect;
|
||||
};
|
||||
|
||||
|
||||
void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||
const gfxRect& aFrameRect,
|
||||
const gfxRect& aDirtyRect)
|
||||
@ -2862,33 +2844,20 @@ void nsPluginInstanceOwner::Paint(gfxContext* aContext,
|
||||
mInstance->GetDrawingModel(&model);
|
||||
|
||||
if (model == kSurface_ANPDrawingModel) {
|
||||
AddPluginView(aFrameRect);
|
||||
|
||||
{
|
||||
ANPEvent event;
|
||||
event.inSize = sizeof(ANPEvent);
|
||||
event.eventType = kLifecycle_ANPEventType;
|
||||
event.data.lifecycle.action = kOnScreen_ANPLifecycleAction;
|
||||
mInstance->HandleEvent(&event, nsnull);
|
||||
gfxImageSurface* pluginSurface = mInstance->LockTargetSurface();
|
||||
if (!pluginSurface) {
|
||||
mInstance->UnlockTargetSurface(false);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
gfxMatrix currentMatrix = aContext->CurrentMatrix();
|
||||
gfxSize scale = currentMatrix.ScaleFactors(true);
|
||||
printf_stderr("!!!!!!!! scale!!: %f x %f\n", scale.width, scale.height);
|
||||
*/
|
||||
aContext->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
aContext->SetSource(pluginSurface, gfxPoint(aFrameRect.x, aFrameRect.y));
|
||||
aContext->Clip(aDirtyRect);
|
||||
aContext->Paint();
|
||||
|
||||
JNIEnv* env = GetJNIForThread();
|
||||
jclass cls = env->FindClass("org/mozilla/gecko/GeckoAppShell");
|
||||
jmethodID method = env->GetStaticMethodID(cls,
|
||||
"addPluginView",
|
||||
"(Landroid/view/View;DDDD)V");
|
||||
env->CallStaticVoidMethod(cls,
|
||||
method,
|
||||
mInstance->GetJavaSurface(),
|
||||
aFrameRect.x,
|
||||
aFrameRect.y,
|
||||
aFrameRect.width,
|
||||
aFrameRect.height);
|
||||
mInstance->UnlockTargetSurface(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -309,6 +309,7 @@ private:
|
||||
|
||||
void FixUpURLS(const nsString &name, nsAString &value);
|
||||
#ifdef ANDROID
|
||||
void AddPluginView(const gfxRect& aRect);
|
||||
void RemovePluginView();
|
||||
#endif
|
||||
|
||||
|
@ -1355,10 +1355,7 @@ public class GeckoAppShell
|
||||
(int)y);
|
||||
|
||||
if (GeckoApp.mainLayout.indexOfChild(view) == -1) {
|
||||
view.setWillNotDraw(false);
|
||||
if(view instanceof SurfaceView)
|
||||
((SurfaceView)view).setZOrderOnTop(true);
|
||||
|
||||
view.setWillNotDraw(true);
|
||||
GeckoApp.mainLayout.addView(view, lp);
|
||||
}
|
||||
else
|
||||
@ -1412,16 +1409,9 @@ public class GeckoAppShell
|
||||
return null;
|
||||
}
|
||||
|
||||
static HashMap<SurfaceView, SurfaceLockInfo> sSufaceMap = new HashMap<SurfaceView, SurfaceLockInfo>();
|
||||
|
||||
public static void lockSurfaceANP()
|
||||
public static SurfaceInfo getSurfaceInfo(SurfaceView sview)
|
||||
{
|
||||
Log.i("GeckoAppShell", "other lockSurfaceANP");
|
||||
}
|
||||
|
||||
public static org.mozilla.gecko.SurfaceLockInfo lockSurfaceANP(android.view.SurfaceView sview, int top, int left, int bottom, int right)
|
||||
{
|
||||
Log.i("GeckoAppShell", "real lockSurfaceANP " + sview + ", " + top + ", " + left + ", " + bottom + ", " + right);
|
||||
Log.i("GeckoAppShell", "getSurfaceInfo " + sview);
|
||||
if (sview == null)
|
||||
return null;
|
||||
|
||||
@ -1435,80 +1425,28 @@ public class GeckoAppShell
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
if (format == PixelFormat.RGB_565)
|
||||
if (format == PixelFormat.RGB_565) {
|
||||
n = 2;
|
||||
else if (format == PixelFormat.RGBA_8888)
|
||||
} else if (format == PixelFormat.RGBA_8888) {
|
||||
n = 4;
|
||||
|
||||
if (n == 0)
|
||||
} else {
|
||||
Log.i("GeckoAppShell", "Unknown pixel format: " + format);
|
||||
return null;
|
||||
|
||||
SurfaceLockInfo info = sSufaceMap.get(sview);
|
||||
if (info == null) {
|
||||
info = new SurfaceLockInfo();
|
||||
sSufaceMap.put(sview, info);
|
||||
}
|
||||
|
||||
Rect r = new Rect(left, top, right, bottom);
|
||||
|
||||
info.canvas = sview.getHolder().lockCanvas(r);
|
||||
int bufSizeRequired = info.canvas.getWidth() * info.canvas.getHeight() * n;
|
||||
Log.i("GeckoAppShell", "lockSurfaceANP - bufSizeRequired: " + n + " " + info.canvas.getHeight() + " " + info.canvas.getWidth());
|
||||
|
||||
if (info.width != info.canvas.getWidth() || info.height != info.canvas.getHeight() || info.buffer == null || info.buffer.capacity() < bufSizeRequired) {
|
||||
info.width = info.canvas.getWidth();
|
||||
info.height = info.canvas.getHeight();
|
||||
|
||||
// XXX Bitmaps instead of ByteBuffer
|
||||
info.buffer = ByteBuffer.allocateDirect(bufSizeRequired); //leak
|
||||
Log.i("GeckoAppShell", "!!!!!!!!!!! lockSurfaceANP - Allocating buffer! " + bufSizeRequired);
|
||||
|
||||
}
|
||||
|
||||
info.canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);
|
||||
SurfaceInfo info = new SurfaceInfo();
|
||||
|
||||
Rect r = sview.getHolder().getSurfaceFrame();
|
||||
info.width = r.right;
|
||||
info.height = r.bottom;
|
||||
info.format = format;
|
||||
info.dirtyTop = top;
|
||||
info.dirtyBottom = bottom;
|
||||
info.dirtyLeft = left;
|
||||
info.dirtyRight = right;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public static void unlockSurfaceANP(SurfaceView sview) {
|
||||
SurfaceLockInfo info = sSufaceMap.get(sview);
|
||||
|
||||
int n = 0;
|
||||
Bitmap.Config config;
|
||||
if (info.format == PixelFormat.RGB_565) {
|
||||
n = 2;
|
||||
config = Bitmap.Config.RGB_565;
|
||||
} else {
|
||||
n = 4;
|
||||
config = Bitmap.Config.ARGB_8888;
|
||||
}
|
||||
|
||||
Log.i("GeckoAppShell", "unlockSurfaceANP: " + (info.width * info.height * n));
|
||||
|
||||
Bitmap bm = Bitmap.createBitmap(info.width, info.height, config);
|
||||
bm.copyPixelsFromBuffer(info.buffer);
|
||||
info.canvas.drawBitmap(bm, 0, 0, null);
|
||||
sview.getHolder().unlockCanvasAndPost(info.canvas);
|
||||
}
|
||||
|
||||
public static Class getSurfaceLockInfoClass() {
|
||||
Log.i("GeckoAppShell", "class name: " + SurfaceLockInfo.class.getName());
|
||||
return SurfaceLockInfo.class;
|
||||
}
|
||||
|
||||
public static Method getSurfaceLockMethod() {
|
||||
Method[] m = GeckoAppShell.class.getMethods();
|
||||
for (int i = 0; i < m.length; i++) {
|
||||
if (m[i].getName().equals("lockSurfaceANP"))
|
||||
return m[i];
|
||||
}
|
||||
return null;
|
||||
public static Class getSurfaceInfoClass() {
|
||||
Log.i("GeckoAppShell", "class name: " + SurfaceInfo.class.getName());
|
||||
return SurfaceInfo.class;
|
||||
}
|
||||
|
||||
static native void executeNextRunnable();
|
||||
|
@ -53,7 +53,7 @@ JAVAFILES = \
|
||||
GeckoSurfaceView.java \
|
||||
GeckoInputConnection.java \
|
||||
AlertNotification.java \
|
||||
SurfaceLockInfo.java \
|
||||
SurfaceInfo.java \
|
||||
$(NULL)
|
||||
|
||||
PROCESSEDJAVAFILES = \
|
||||
|
7
embedding/android/SurfaceInfo.java
Normal file
7
embedding/android/SurfaceInfo.java
Normal file
@ -0,0 +1,7 @@
|
||||
package org.mozilla.gecko;
|
||||
|
||||
public class SurfaceInfo {
|
||||
public int format;
|
||||
public int width;
|
||||
public int height;
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import java.nio.Buffer;
|
||||
|
||||
public class SurfaceLockInfo {
|
||||
public int dirtyTop;
|
||||
public int dirtyLeft;
|
||||
public int dirtyRight;
|
||||
public int dirtyBottom;
|
||||
|
||||
public int bpr;
|
||||
public int format;
|
||||
public int width;
|
||||
public int height;
|
||||
public Buffer buffer;
|
||||
public Canvas canvas;
|
||||
}
|
Loading…
Reference in New Issue
Block a user