mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merging mozilla-central with mozilla-inbound.
This commit is contained in:
commit
12c71e7bf0
@ -74,11 +74,11 @@ let AllTabs = {
|
||||
*/
|
||||
register: function register(eventName, callback) {
|
||||
// Either add additional callbacks or create the first entry
|
||||
let listeners = eventListeners[eventName];
|
||||
let listeners = eventListeners[events[eventName]];
|
||||
if (listeners)
|
||||
listeners.push(callback);
|
||||
else
|
||||
eventListeners[eventName] = [callback];
|
||||
eventListeners[events[eventName]] = [callback];
|
||||
},
|
||||
|
||||
/**
|
||||
@ -93,7 +93,7 @@ let AllTabs = {
|
||||
*/
|
||||
unregister: function unregister(eventName, callback) {
|
||||
// Nothing to remove for this event
|
||||
let listeners = eventListeners[eventName];
|
||||
let listeners = eventListeners[events[eventName]];
|
||||
if (!listeners)
|
||||
return;
|
||||
|
||||
@ -114,31 +114,50 @@ __defineGetter__("browserWindows", function browserWindows() {
|
||||
return browserWindows;
|
||||
});
|
||||
|
||||
let events = ["attrModified", "close", "move", "open", "select", "pinned", "unpinned"];
|
||||
let events = {
|
||||
attrModified: "TabAttrModified",
|
||||
close: "TabClose",
|
||||
move: "TabMove",
|
||||
open: "TabOpen",
|
||||
select: "TabSelect",
|
||||
pinned: "TabPinned",
|
||||
unpinned: "TabUnpinned"
|
||||
};
|
||||
let eventListeners = {};
|
||||
|
||||
function registerBrowserWindow(browserWindow) {
|
||||
events.forEach(function(eventName) {
|
||||
let tabEvent = "Tab" + eventName[0].toUpperCase() + eventName.slice(1);
|
||||
browserWindow.addEventListener(tabEvent, function(event) {
|
||||
// Make sure we've gotten listeners before trying to call
|
||||
let listeners = eventListeners[eventName];
|
||||
if (!listeners)
|
||||
return;
|
||||
for each (let event in events)
|
||||
browserWindow.addEventListener(event, tabEventListener, true);
|
||||
|
||||
let tab = event.target;
|
||||
browserWindow.addEventListener("unload", unregisterBrowserWindow, false);
|
||||
}
|
||||
|
||||
// Make a copy of the listeners, so it can't change as we call back
|
||||
listeners.slice().forEach(function(callback) {
|
||||
try {
|
||||
callback(tab, event);
|
||||
}
|
||||
// Don't let failing callbacks stop us but report the failure
|
||||
catch(ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
});
|
||||
}, true);
|
||||
function unregisterBrowserWindow(unloadEvent) {
|
||||
let browserWindow = unloadEvent.currentTarget;
|
||||
|
||||
for each (let event in events)
|
||||
browserWindow.removeEventListener(event, tabEventListener, true);
|
||||
|
||||
browserWindow.removeEventListener("unload", unregisterBrowserWindow, false);
|
||||
}
|
||||
|
||||
function tabEventListener(event) {
|
||||
// Make sure we've gotten listeners before trying to call
|
||||
let listeners = eventListeners[event.type];
|
||||
if (!listeners)
|
||||
return;
|
||||
|
||||
let tab = event.target;
|
||||
|
||||
// Make a copy of the listeners, so it can't change as we call back
|
||||
listeners.slice().forEach(function (callback) {
|
||||
try {
|
||||
callback(tab, event);
|
||||
}
|
||||
// Don't let failing callbacks stop us but report the failure
|
||||
catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,13 @@ defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/
|
||||
defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
|
||||
defaults/profile/search.rdf
|
||||
#ifndef SHIP_FEEDBACK
|
||||
# In the average case, this directory is only used by Test Pilot, and will get
|
||||
# removed by the updater. In some cases (eg, partner builds), distribution/
|
||||
# will have other files and/or directories in it. In these cases, the updater
|
||||
# will print a non-fatal error and continue on, because we're not appending
|
||||
# '*' to force a recursive removal.
|
||||
distribution/
|
||||
distribution/extensions/
|
||||
distribution/extensions/testpilot@labs.mozilla.com.xpi
|
||||
#endif
|
||||
extensions/talkback@mozilla.org/
|
||||
@ -267,7 +274,6 @@ res/ua.css
|
||||
res/unixcharset.properties
|
||||
res/viewsource.css
|
||||
res/wincharset.properties
|
||||
searchplugins/
|
||||
searchplugins/DRAE.gif
|
||||
searchplugins/DRAE.png
|
||||
searchplugins/DRAE.src
|
||||
|
@ -1904,9 +1904,10 @@ public:
|
||||
nsInProcessTabChildGlobal* tabChild =
|
||||
static_cast<nsInProcessTabChildGlobal*>(mFrameLoader->mChildMessageManager.get());
|
||||
if (tabChild && tabChild->GetInnerManager()) {
|
||||
tabChild->GetInnerManager()->
|
||||
ReceiveMessage(static_cast<nsPIDOMEventTarget*>(tabChild), mMessage,
|
||||
PR_FALSE, mJSON, nsnull, nsnull);
|
||||
nsFrameScriptCx cx(static_cast<nsPIDOMEventTarget*>(tabChild), tabChild);
|
||||
nsRefPtr<nsFrameMessageManager> mm = tabChild->GetInnerManager();
|
||||
mm->ReceiveMessage(static_cast<nsPIDOMEventTarget*>(tabChild), mMessage,
|
||||
PR_FALSE, mJSON, nsnull, nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -462,6 +462,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
||||
}
|
||||
}
|
||||
}
|
||||
nsRefPtr<nsFrameMessageManager> kungfuDeathGrip = mParentManager;
|
||||
return mParentManager ? mParentManager->ReceiveMessage(aTarget, aMessage,
|
||||
aSync, aJSON, aObjectsArray,
|
||||
aJSONRetVal, mContext) : NS_OK;
|
||||
@ -601,11 +602,18 @@ nsFrameScriptExecutor::DidCreateCx()
|
||||
void
|
||||
nsFrameScriptExecutor::DestroyCx()
|
||||
{
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
xpc->ReleaseJSContext(mCx, PR_TRUE);
|
||||
} else {
|
||||
JS_DestroyContext(mCx);
|
||||
if (mCxStackRefCnt) {
|
||||
mDelayedCxDestroy = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
mDelayedCxDestroy = PR_FALSE;
|
||||
if (mCx) {
|
||||
nsIXPConnect* xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
xpc->ReleaseJSContext(mCx, PR_TRUE);
|
||||
} else {
|
||||
JS_DestroyContext(mCx);
|
||||
}
|
||||
}
|
||||
mCx = nsnull;
|
||||
mGlobal = nsnull;
|
||||
|
@ -201,7 +201,9 @@ class nsFrameScriptExecutor
|
||||
public:
|
||||
static void Shutdown();
|
||||
protected:
|
||||
nsFrameScriptExecutor() : mCx(nsnull)
|
||||
friend class nsFrameScriptCx;
|
||||
nsFrameScriptExecutor() : mCx(nsnull), mCxStackRefCnt(0),
|
||||
mDelayedCxDestroy(PR_FALSE)
|
||||
{ MOZ_COUNT_CTOR(nsFrameScriptExecutor); }
|
||||
~nsFrameScriptExecutor()
|
||||
{ MOZ_COUNT_DTOR(nsFrameScriptExecutor); }
|
||||
@ -213,11 +215,32 @@ protected:
|
||||
nsCycleCollectionTraversalCallback &cb);
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> mGlobal;
|
||||
JSContext* mCx;
|
||||
PRUint32 mCxStackRefCnt;
|
||||
PRPackedBool mDelayedCxDestroy;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
static nsDataHashtable<nsStringHashKey, nsFrameScriptExecutorJSObjectHolder*>* sCachedScripts;
|
||||
static nsRefPtr<nsScriptCacheCleaner> sScriptCacheCleaner;
|
||||
};
|
||||
|
||||
class nsFrameScriptCx
|
||||
{
|
||||
public:
|
||||
nsFrameScriptCx(nsISupports* aOwner, nsFrameScriptExecutor* aExec)
|
||||
: mOwner(aOwner), mExec(aExec)
|
||||
{
|
||||
++(mExec->mCxStackRefCnt);
|
||||
}
|
||||
~nsFrameScriptCx()
|
||||
{
|
||||
if (--(mExec->mCxStackRefCnt) == 0 &&
|
||||
mExec->mDelayedCxDestroy) {
|
||||
mExec->DestroyCx();
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsFrameScriptExecutor* mExec;
|
||||
};
|
||||
|
||||
class nsScriptCacheCleaner : public nsIObserver
|
||||
{
|
||||
NS_DECL_ISUPPORTS
|
||||
|
@ -68,8 +68,8 @@ bool SendSyncMessageToParent(void* aCallbackData,
|
||||
async->Run();
|
||||
}
|
||||
if (tabChild->mChromeMessageManager) {
|
||||
tabChild->mChromeMessageManager->ReceiveMessage(owner, aMessage, PR_TRUE,
|
||||
aJSON, nsnull, aJSONRetVal);
|
||||
nsRefPtr<nsFrameMessageManager> mm = tabChild->mChromeMessageManager;
|
||||
mm->ReceiveMessage(owner, aMessage, PR_TRUE, aJSON, nsnull, aJSONRetVal);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -85,9 +85,9 @@ public:
|
||||
{
|
||||
mTabChild->mASyncMessages.RemoveElement(this);
|
||||
if (mTabChild->mChromeMessageManager) {
|
||||
mTabChild->mChromeMessageManager->ReceiveMessage(mTabChild->mOwner, mMessage,
|
||||
PR_FALSE,
|
||||
mJSON, nsnull, nsnull);
|
||||
nsRefPtr<nsFrameMessageManager> mm = mTabChild->mChromeMessageManager;
|
||||
mm->ReceiveMessage(mTabChild->mOwner, mMessage, PR_FALSE,
|
||||
mJSON, nsnull, nsnull);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3913,6 +3913,8 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
|
||||
case NS_ERROR_DOCUMENT_NOT_CACHED:
|
||||
// Doc failed to load because we are offline and the cache does not
|
||||
// contain a copy of the document.
|
||||
case NS_ERROR_OFFLINE:
|
||||
// Doc failed to load because we are offline
|
||||
error.AssignLiteral("netOffline");
|
||||
break;
|
||||
case NS_ERROR_DOCUMENT_IS_PRINTMODE:
|
||||
@ -6278,6 +6280,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
|
||||
aStatus == NS_ERROR_UNKNOWN_SOCKET_TYPE ||
|
||||
aStatus == NS_ERROR_NET_INTERRUPT ||
|
||||
aStatus == NS_ERROR_NET_RESET ||
|
||||
aStatus == NS_ERROR_OFFLINE ||
|
||||
aStatus == NS_ERROR_MALWARE_URI ||
|
||||
aStatus == NS_ERROR_PHISHING_URI ||
|
||||
aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
|
||||
|
@ -220,7 +220,7 @@ ContentParent::OnChannelConnected(int32 pid)
|
||||
nice = atoi(relativeNicenessStr);
|
||||
}
|
||||
|
||||
/* make the GUI thread have higher priority on single-cpu devices */
|
||||
/* make the GUI thread have higher priority on single-cpu devices */
|
||||
nsCOMPtr<nsIPropertyBag2> infoService = do_GetService(NS_SYSTEMINFO_CONTRACTID);
|
||||
if (infoService) {
|
||||
PRInt32 cpus;
|
||||
|
@ -145,6 +145,7 @@ TabChild::Init()
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(TabChild)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebBrowserChrome)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
|
||||
@ -754,9 +755,11 @@ TabChild::RecvAsyncMessage(const nsString& aMessage,
|
||||
const nsString& aJSON)
|
||||
{
|
||||
if (mTabChildGlobal) {
|
||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get())->
|
||||
ReceiveMessage(static_cast<nsPIDOMEventTarget*>(mTabChildGlobal),
|
||||
aMessage, PR_FALSE, aJSON, nsnull, nsnull);
|
||||
nsFrameScriptCx cx(static_cast<nsIWebBrowserChrome*>(this), this);
|
||||
nsRefPtr<nsFrameMessageManager> mm =
|
||||
static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
|
||||
mm->ReceiveMessage(static_cast<nsPIDOMEventTarget*>(mTabChildGlobal),
|
||||
aMessage, PR_FALSE, aJSON, nsnull, nsnull);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -587,7 +587,8 @@ TabParent::ReceiveMessage(const nsString& aMessage,
|
||||
{
|
||||
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
|
||||
if (frameLoader && frameLoader->GetFrameMessageManager()) {
|
||||
nsFrameMessageManager* manager = frameLoader->GetFrameMessageManager();
|
||||
nsRefPtr<nsFrameMessageManager> manager =
|
||||
frameLoader->GetFrameMessageManager();
|
||||
JSContext* ctx = manager->GetJSContext();
|
||||
JSAutoRequest ar(ctx);
|
||||
PRUint32 len = 0; //TODO: obtain a real value in bug 572685
|
||||
|
@ -139,7 +139,7 @@ abstract public class GeckoApp
|
||||
mLibLoadThread.join();
|
||||
} catch (InterruptedException ie) {}
|
||||
surfaceView.mSplashStatusMsg =
|
||||
getResources().getString(R.string.splash_screen_label);
|
||||
getResources().getString(R.string.splash_screen_loading);
|
||||
surfaceView.drawSplashScreen();
|
||||
// unpack files in the components directory
|
||||
try {
|
||||
@ -260,10 +260,10 @@ abstract public class GeckoApp
|
||||
new File(getApplication().getPackageResourcePath()).lastModified()
|
||||
>= libxulFile.lastModified()))
|
||||
surfaceView.mSplashStatusMsg =
|
||||
getResources().getString(R.string.splash_screen_installing);
|
||||
getResources().getString(R.string.splash_screen_installing_libs);
|
||||
else
|
||||
surfaceView.mSplashStatusMsg =
|
||||
getResources().getString(R.string.splash_screen_label);
|
||||
getResources().getString(R.string.splash_screen_loading);
|
||||
mLibLoadThread.start();
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,7 @@ public class GeckoInputConnection
|
||||
|
||||
// 2. Make a guess about what the text actually is
|
||||
if (mComposing && extract.selectionEnd > extract.text.length())
|
||||
extract.text = extract.text.subSequence(0, mCompositionStart) + mComposingText;
|
||||
extract.text = extract.text.subSequence(0, Math.min(extract.text.length(), mCompositionStart)) + mComposingText;
|
||||
|
||||
// 3. If all else fails, make sure our selection indexes make sense
|
||||
extract.selectionStart = Math.min(extract.selectionStart, extract.text.length());
|
||||
|
@ -132,6 +132,40 @@ class GeckoSurfaceView
|
||||
* Called on main thread
|
||||
*/
|
||||
|
||||
public void draw(SurfaceHolder holder, ByteBuffer buffer) {
|
||||
if (buffer == null || buffer.capacity() != (mWidth * mHeight * 2))
|
||||
return;
|
||||
|
||||
synchronized (mSoftwareBuffer) {
|
||||
if (buffer != mSoftwareBuffer || mSoftwareBufferCopy == null)
|
||||
return;
|
||||
|
||||
Canvas c = holder.lockCanvas();
|
||||
if (c == null)
|
||||
return;
|
||||
mSoftwareBufferCopy.copyPixelsFromBuffer(buffer);
|
||||
c.drawBitmap(mSoftwareBufferCopy, 0, 0, null);
|
||||
holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(SurfaceHolder holder, Bitmap bitmap) {
|
||||
if (bitmap == null ||
|
||||
bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight)
|
||||
return;
|
||||
|
||||
synchronized (mSoftwareBitmap) {
|
||||
if (bitmap != mSoftwareBitmap)
|
||||
return;
|
||||
|
||||
Canvas c = holder.lockCanvas();
|
||||
if (c == null)
|
||||
return;
|
||||
c.drawBitmap(bitmap, 0, 0, null);
|
||||
holder.unlockCanvasAndPost(c);
|
||||
}
|
||||
}
|
||||
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
if (mShowingSplashScreen)
|
||||
drawSplashScreen(holder, width, height);
|
||||
@ -142,14 +176,15 @@ class GeckoSurfaceView
|
||||
Log.w("GeckoAppJava", "surfaceChanged while mInDrawing is true!");
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
if (width == 0 || height == 0) {
|
||||
mSoftwareBitmap = null;
|
||||
mSoftwareBuffer = null;
|
||||
else if (mSoftwareBuffer == null ||
|
||||
mSoftwareBuffer.capacity() < (width * height * 2) ||
|
||||
mWidth != width || mHeight != height)
|
||||
mSoftwareBuffer = ByteBuffer.allocateDirect(width * height * 2);
|
||||
boolean doSyncDraw = mDrawMode == DRAW_2D &&
|
||||
mSoftwareBuffer != null &&
|
||||
mSoftwareBufferCopy = null;
|
||||
}
|
||||
|
||||
boolean doSyncDraw =
|
||||
mDrawMode == DRAW_2D &&
|
||||
(mSoftwareBitmap != null || mSoftwareBuffer != null) &&
|
||||
GeckoApp.checkLaunchState(GeckoApp.LaunchState.GeckoRunning);
|
||||
mSyncDraw = doSyncDraw;
|
||||
|
||||
@ -167,7 +202,7 @@ class GeckoSurfaceView
|
||||
metrics.widthPixels, metrics.heightPixels);
|
||||
GeckoAppShell.sendEventToGecko(e);
|
||||
|
||||
if (mSoftwareBuffer != null)
|
||||
if (mSoftwareBitmap != null || mSoftwareBuffer != null)
|
||||
GeckoAppShell.scheduleRedraw();
|
||||
|
||||
if (!doSyncDraw) {
|
||||
@ -182,18 +217,17 @@ class GeckoSurfaceView
|
||||
mSurfaceLock.unlock();
|
||||
}
|
||||
|
||||
ByteBuffer bb = null;
|
||||
Object syncDrawObject = null;
|
||||
try {
|
||||
bb = mSyncBuf.take();
|
||||
Object syncObject = mSyncDraws.take();
|
||||
} catch (InterruptedException ie) {
|
||||
Log.e("GeckoAppJava", "Threw exception while getting sync buf: ", ie);
|
||||
Log.e("GeckoAppJava", "Threw exception while getting sync draw bitmap/buffer: ", ie);
|
||||
}
|
||||
if (bb != null && bb.capacity() == (width * height * 2)) {
|
||||
mSoftwareBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565);
|
||||
mSoftwareBitmap.copyPixelsFromBuffer(bb);
|
||||
Canvas c = holder.lockCanvas();
|
||||
c.drawBitmap(mSoftwareBitmap, 0, 0, null);
|
||||
holder.unlockCanvasAndPost(c);
|
||||
if (syncDrawObject != null) {
|
||||
if (syncDrawObject instanceof Bitmap)
|
||||
draw(holder, (Bitmap)syncDrawObject);
|
||||
else
|
||||
draw(holder, (ByteBuffer)syncDrawObject);
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,11 +243,37 @@ class GeckoSurfaceView
|
||||
Log.i("GeckoAppJava", "surface destroyed");
|
||||
mSurfaceValid = false;
|
||||
mSoftwareBuffer = null;
|
||||
mSoftwareBufferCopy = null;
|
||||
mSoftwareBitmap = null;
|
||||
GeckoEvent e = new GeckoEvent(GeckoEvent.SURFACE_DESTROYED);
|
||||
GeckoAppShell.sendEventToGecko(e);
|
||||
}
|
||||
|
||||
public Bitmap getSoftwareDrawBitmap() {
|
||||
if (mSoftwareBitmap == null ||
|
||||
mSoftwareBitmap.getHeight() != mHeight ||
|
||||
mSoftwareBitmap.getWidth() != mWidth) {
|
||||
mSoftwareBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565);
|
||||
}
|
||||
|
||||
mDrawMode = DRAW_2D;
|
||||
return mSoftwareBitmap;
|
||||
}
|
||||
|
||||
public ByteBuffer getSoftwareDrawBuffer() {
|
||||
// We store pixels in 565 format, so two bytes per pixel (explaining
|
||||
// the * 2 in the following check/allocation)
|
||||
if (mSoftwareBuffer == null ||
|
||||
mSoftwareBuffer.capacity() != (mWidth * mHeight * 2)) {
|
||||
mSoftwareBuffer = ByteBuffer.allocateDirect(mWidth * mHeight * 2);
|
||||
}
|
||||
|
||||
if (mSoftwareBufferCopy == null ||
|
||||
mSoftwareBufferCopy.getHeight() != mHeight ||
|
||||
mSoftwareBufferCopy.getWidth() != mWidth) {
|
||||
mSoftwareBufferCopy = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565);
|
||||
}
|
||||
|
||||
mDrawMode = DRAW_2D;
|
||||
return mSoftwareBuffer;
|
||||
}
|
||||
@ -290,19 +350,19 @@ class GeckoSurfaceView
|
||||
* unless you're in SurfaceChanged, in which case the canvas was already
|
||||
* locked. Surface lock -> Canvas lock will lead to AB-BA deadlocks.
|
||||
*/
|
||||
public void draw2D(ByteBuffer buffer, int stride) {
|
||||
// mSurfaceLock ensures that we get mSyncDraw/mSoftwareBuffer/etc.
|
||||
public void draw2D(Bitmap bitmap, int width, int height) {
|
||||
// mSurfaceLock ensures that we get mSyncDraw/mSoftwareBitmap/etc.
|
||||
// set correctly before determining whether we should do a sync draw
|
||||
mSurfaceLock.lock();
|
||||
try {
|
||||
if (mSyncDraw) {
|
||||
if (buffer != mSoftwareBuffer || stride != (mWidth * 2))
|
||||
if (bitmap != mSoftwareBitmap || width != mWidth || height != mHeight)
|
||||
return;
|
||||
mSyncDraw = false;
|
||||
try {
|
||||
mSyncBuf.put(buffer);
|
||||
mSyncDraws.put(bitmap);
|
||||
} catch (InterruptedException ie) {
|
||||
Log.e("GeckoAppJava", "Threw exception while getting sync buf: ", ie);
|
||||
Log.e("GeckoAppJava", "Threw exception while getting sync draws queue: ", ie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -310,29 +370,28 @@ class GeckoSurfaceView
|
||||
mSurfaceLock.unlock();
|
||||
}
|
||||
|
||||
if (buffer != mSoftwareBuffer || stride != (mWidth * 2))
|
||||
return;
|
||||
Canvas c = getHolder().lockCanvas();
|
||||
if (c == null)
|
||||
return;
|
||||
if (buffer != mSoftwareBuffer || stride != (mWidth * 2)) {
|
||||
/* We're screwed. Fill it with white and hope it isn't too noticable
|
||||
* This could potentially happen if this function is called
|
||||
* right before mSurfaceLock is locked in SurfaceChanged.
|
||||
* However, I've never actually seen this code get hit.
|
||||
*/
|
||||
c.drawARGB(255, 255, 255, 255);
|
||||
getHolder().unlockCanvasAndPost(c);
|
||||
return;
|
||||
draw(getHolder(), bitmap);
|
||||
}
|
||||
|
||||
public void draw2D(ByteBuffer buffer, int stride) {
|
||||
mSurfaceLock.lock();
|
||||
try {
|
||||
if (mSyncDraw) {
|
||||
if (buffer != mSoftwareBuffer || stride != (mWidth * 2))
|
||||
return;
|
||||
mSyncDraw = false;
|
||||
try {
|
||||
mSyncDraws.put(buffer);
|
||||
} catch (InterruptedException ie) {
|
||||
Log.e("GeckoAppJava", "Threw exception while getting sync bitmaps queue: ", ie);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
mSurfaceLock.unlock();
|
||||
}
|
||||
if (mSoftwareBitmap == null ||
|
||||
mSoftwareBitmap.getHeight() != mHeight ||
|
||||
mSoftwareBitmap.getWidth() != mWidth) {
|
||||
mSoftwareBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.RGB_565);
|
||||
}
|
||||
mSoftwareBitmap.copyPixelsFromBuffer(mSoftwareBuffer);
|
||||
c.drawBitmap(mSoftwareBitmap, 0, 0, null);
|
||||
getHolder().unlockCanvasAndPost(c);
|
||||
|
||||
draw(getHolder(), buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -631,12 +690,13 @@ class GeckoSurfaceView
|
||||
boolean mIMELandscapeFS;
|
||||
|
||||
// Software rendering
|
||||
ByteBuffer mSoftwareBuffer;
|
||||
Bitmap mSoftwareBitmap;
|
||||
ByteBuffer mSoftwareBuffer;
|
||||
Bitmap mSoftwareBufferCopy;
|
||||
|
||||
Geocoder mGeocoder;
|
||||
Address mLastGeoAddress;
|
||||
|
||||
final SynchronousQueue<ByteBuffer> mSyncBuf = new SynchronousQueue<ByteBuffer>();
|
||||
final SynchronousQueue<Object> mSyncDraws = new SynchronousQueue<Object>();
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
<!ENTITY splash_screen_label "loading">
|
||||
<!ENTITY splash_screen_installing "installing libraries\u2026">
|
||||
|
||||
<!ENTITY splash_screen_loading "Loading">
|
||||
<!ENTITY splash_screen_installing_libs "Installing libraries\u2026">
|
||||
<!ENTITY splash_firstrun "Setting up &brandShortName;\u2026">
|
||||
|
||||
<!ENTITY no_space_to_start_error "There is not enough space available for &brandShortName; to start.">
|
||||
<!ENTITY error_loading_file "An error occurred when trying to load files required to run &brandShortName;">
|
||||
|
||||
|
@ -5,8 +5,8 @@
|
||||
#includesubst @STRINGSPATH@
|
||||
]>
|
||||
<resources>
|
||||
<string name="splash_screen_label">&splash_screen_label;</string>
|
||||
<string name="splash_screen_installing">&splash_screen_installing;</string>
|
||||
<string name="splash_screen_loading">&splash_screen_loading;</string>
|
||||
<string name="splash_screen_installing_libs">&splash_screen_installing_libs;</string>
|
||||
<string name="splash_firstrun">&splash_firstrun;</string>
|
||||
<string name="no_space_to_start_error">&no_space_to_start_error;</string>
|
||||
<string name="error_loading_file">&error_loading_file;</string>
|
||||
|
@ -297,6 +297,7 @@ EXPORTS_NAMESPACES += mozilla
|
||||
|
||||
EXPORTS_mozilla = \
|
||||
RangedPtr.h \
|
||||
RefPtr.h \
|
||||
Types.h \
|
||||
Util.h \
|
||||
$(NULL)
|
||||
|
@ -1762,6 +1762,10 @@ DocumentViewerImpl::SetDocumentInternal(nsIDocument* aDocument,
|
||||
aDocument->SetContainer(container);
|
||||
|
||||
if (mDocument != aDocument) {
|
||||
if (mDocument->IsStaticDocument()) {
|
||||
mDocument->SetScriptGlobalObject(nsnull);
|
||||
mDocument->Destroy();
|
||||
}
|
||||
// Replace the old document with the new one. Do this only when
|
||||
// the new document really is a new document.
|
||||
mDocument = aDocument;
|
||||
|
@ -3322,10 +3322,14 @@ nsTextPaintStyle::GetURLSecondaryColor(nscolor* aForeColor)
|
||||
{
|
||||
NS_ASSERTION(aForeColor, "aForeColor is null");
|
||||
|
||||
nsILookAndFeel* look = mPresContext->LookAndFeel();
|
||||
nscolor foreColor;
|
||||
look->GetColor(nsILookAndFeel::eColor_graytext, foreColor);
|
||||
*aForeColor = foreColor;
|
||||
nscolor textColor = GetTextColor();
|
||||
textColor = NS_RGBA(NS_GET_R(textColor),
|
||||
NS_GET_G(textColor),
|
||||
NS_GET_B(textColor),
|
||||
(PRUint8)(255 * 0.5f));
|
||||
// Don't use true alpha color for readability.
|
||||
InitCommonColors();
|
||||
*aForeColor = NS_ComposeColors(mFrameBackgroundColor, textColor);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -74,7 +74,7 @@ nsPrintData::nsPrintData(ePrintDataType aType) :
|
||||
mShrinkRatio(1.0), mOrigDCScale(1.0), mPPEventListeners(NULL),
|
||||
mBrandName(nsnull)
|
||||
{
|
||||
|
||||
MOZ_COUNT_CTOR(nsPrintData);
|
||||
nsCOMPtr<nsIStringBundle> brandBundle;
|
||||
nsCOMPtr<nsIStringBundleService> svc =
|
||||
mozilla::services::GetStringBundleService();
|
||||
@ -93,6 +93,7 @@ nsPrintData::nsPrintData(ePrintDataType aType) :
|
||||
|
||||
nsPrintData::~nsPrintData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsPrintData);
|
||||
// remove the event listeners
|
||||
if (mPPEventListeners) {
|
||||
mPPEventListeners->RemoveListeners();
|
||||
|
@ -55,11 +55,13 @@ nsPrintObject::nsPrintObject() :
|
||||
mSharedPresShell(PR_FALSE), mInvisible(PR_FALSE), mDidCreateDocShell(PR_FALSE),
|
||||
mShrinkRatio(1.0), mZoomRatio(1.0)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsPrintObject);
|
||||
}
|
||||
|
||||
|
||||
nsPrintObject::~nsPrintObject()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsPrintObject);
|
||||
for (PRUint32 i=0;i<mKids.Length();i++) {
|
||||
nsPrintObject* po = mKids[i];
|
||||
delete po;
|
||||
|
413
mfbt/RefPtr.h
Normal file
413
mfbt/RefPtr.h
Normal file
@ -0,0 +1,413 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Chris Jones <jones.chris.g@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_RefPtr_h_
|
||||
#define mozilla_RefPtr_h_
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
/**
|
||||
* Helpers for defining and using refcounted objects.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
template<typename T> class RefCounted;
|
||||
template<typename T> class RefPtr;
|
||||
template<typename T> class TemporaryRef;
|
||||
template<typename T> class OutParamRef;
|
||||
template<typename T> OutParamRef<T> byRef(RefPtr<T>&);
|
||||
|
||||
/**
|
||||
* RefCounted<T> is a sort of a "mixin" for a class T. RefCounted
|
||||
* manages, well, refcounting for T, and because RefCounted is
|
||||
* parameterized on T, RefCounted<T> can call T's destructor directly.
|
||||
* This means T doesn't need to have a virtual dtor and so doesn't
|
||||
* need a vtable.
|
||||
*
|
||||
* RefCounted<T> is created with refcount == 0. Newly-allocated
|
||||
* RefCounted<T> must immediately be assigned to a RefPtr to make the
|
||||
* refcount > 0. It's an error to allocate and free a bare
|
||||
* RefCounted<T>, i.e. outside of the RefPtr machinery. Attempts to
|
||||
* do so will abort DEBUG builds.
|
||||
*
|
||||
* Live RefCounted<T> have refcount > 0. The lifetime (refcounts) of
|
||||
* live RefCounted<T> are controlled by RefPtr<T> and
|
||||
* RefPtr<super/subclass of T>. Upon a transition from refcounted==1
|
||||
* to 0, the RefCounted<T> "dies" and is destroyed. The "destroyed"
|
||||
* state is represented in DEBUG builds by refcount==-0xdead. This
|
||||
* state distinguishes use-before-ref (refcount==0) from
|
||||
* use-after-destroy (refcount==-0xdead).
|
||||
*/
|
||||
template<typename T>
|
||||
class RefCounted
|
||||
{
|
||||
friend class RefPtr<T>;
|
||||
|
||||
public:
|
||||
RefCounted() : refCnt(0) { }
|
||||
~RefCounted() { MOZ_ASSERT(refCnt == -0xdead); }
|
||||
|
||||
// Compatibility with nsRefPtr.
|
||||
void AddRef() {
|
||||
MOZ_ASSERT(refCnt >= 0);
|
||||
++refCnt;
|
||||
}
|
||||
|
||||
void Release() {
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
if (0 == --refCnt) {
|
||||
#ifdef DEBUG
|
||||
refCnt = -0xdead;
|
||||
#endif
|
||||
delete static_cast<T*>(this);
|
||||
}
|
||||
}
|
||||
|
||||
// Compatibility with wtf::RefPtr.
|
||||
void ref() { AddRef(); }
|
||||
void deref() { Release(); }
|
||||
int refCount() const { return refCnt; }
|
||||
bool hasOneRef() const {
|
||||
MOZ_ASSERT(refCnt > 0);
|
||||
return refCnt == 1;
|
||||
}
|
||||
|
||||
private:
|
||||
int refCnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* RefPtr points to a refcounted thing that has AddRef and Release
|
||||
* methods to increase/decrease the refcount, respectively. After a
|
||||
* RefPtr<T> is assigned a T*, the T* can be used through the RefPtr
|
||||
* as if it were a T*.
|
||||
*
|
||||
* A RefPtr can forget its underlying T*, which results in the T*
|
||||
* being wrapped in a temporary object until the T* is either
|
||||
* re-adopted from or released by the temporary.
|
||||
*/
|
||||
template<typename T>
|
||||
class RefPtr
|
||||
{
|
||||
// To allow them to use unref()
|
||||
friend class TemporaryRef<T>;
|
||||
friend class OutParamRef<T>;
|
||||
|
||||
public:
|
||||
RefPtr() : ptr(0) { }
|
||||
RefPtr(const RefPtr& o) : ptr(ref(o.ptr)) {}
|
||||
RefPtr(const TemporaryRef<T>& o) : ptr(o.drop()) {}
|
||||
RefPtr(T* t) : ptr(ref(t)) {}
|
||||
|
||||
template<typename U>
|
||||
RefPtr(const RefPtr<U>& o) : ptr(ref(o.get())) {}
|
||||
|
||||
~RefPtr() { unref(ptr); }
|
||||
|
||||
RefPtr& operator=(const RefPtr& o) {
|
||||
assign(ref(o.ptr));
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(const TemporaryRef<T>& o) {
|
||||
assign(o.drop());
|
||||
return *this;
|
||||
}
|
||||
RefPtr& operator=(T* t) {
|
||||
assign(ref(t));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
RefPtr& operator=(const RefPtr<U>& o) {
|
||||
assign(ref(o.get()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
TemporaryRef<T> forget() {
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return TemporaryRef<T>(tmp);
|
||||
}
|
||||
|
||||
T* get() const { return ptr; }
|
||||
operator T*() const { return ptr; }
|
||||
T* operator->() const { return ptr; }
|
||||
T& operator*() const { return *ptr; }
|
||||
|
||||
private:
|
||||
void assign(T* t) {
|
||||
unref(ptr);
|
||||
ptr = t;
|
||||
}
|
||||
|
||||
T* ptr;
|
||||
|
||||
static MOZ_ALWAYS_INLINE T* ref(T* t) {
|
||||
if (t) {
|
||||
t->AddRef();
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE void unref(T* t) {
|
||||
if (t) {
|
||||
t->Release();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TemporaryRef<T> represents an object that holds a temporary
|
||||
* reference to a T. TemporaryRef objects can't be manually ref'd or
|
||||
* unref'd (being temporaries, not lvalues), so can only relinquish
|
||||
* references to other objects, or unref on destruction.
|
||||
*/
|
||||
template<typename T>
|
||||
class TemporaryRef
|
||||
{
|
||||
// To allow it to construct TemporaryRef from a bare T*
|
||||
friend class RefPtr<T>;
|
||||
|
||||
public:
|
||||
TemporaryRef(const TemporaryRef& o) : ptr(o.drop()) {}
|
||||
|
||||
template<typename U>
|
||||
TemporaryRef(const TemporaryRef<U>& o) : ptr(o.drop()) {}
|
||||
|
||||
~TemporaryRef() { RefPtr<T>::unref(ptr); }
|
||||
|
||||
T* drop() const {
|
||||
T* tmp = ptr;
|
||||
ptr = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private:
|
||||
TemporaryRef(T* t) : ptr(t) {}
|
||||
|
||||
mutable T* ptr;
|
||||
|
||||
TemporaryRef();
|
||||
TemporaryRef& operator=(const TemporaryRef&);
|
||||
};
|
||||
|
||||
/**
|
||||
* OutParamRef is a wrapper that tracks a refcounted pointer passed as
|
||||
* an outparam argument to a function. If OutParamRef holds a ref to
|
||||
* an object that's reassigned during a function call in which the
|
||||
* OutParamRef is an outparam, then the old object is unref'd and the
|
||||
* new object is ref'd.
|
||||
*
|
||||
* Prefer returning TemporaryRef<T> from functions over creating T**
|
||||
* outparams and passing OutParamRef<T> to T**. Prefer RefPtr<T>*
|
||||
* outparams over T** outparams.
|
||||
*/
|
||||
template<typename T>
|
||||
class OutParamRef
|
||||
{
|
||||
friend OutParamRef byRef<T>(RefPtr<T>&);
|
||||
|
||||
public:
|
||||
~OutParamRef() { refPtr = tmp; }
|
||||
|
||||
operator T**() { return &tmp; }
|
||||
|
||||
private:
|
||||
OutParamRef(RefPtr<T>& p) : refPtr(p), tmp(p.get()) {}
|
||||
|
||||
RefPtr<T>& refPtr;
|
||||
T* tmp;
|
||||
|
||||
OutParamRef();
|
||||
OutParamRef& operator=(const OutParamRef&);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
OutParamRef<T>
|
||||
byRef(RefPtr<T>& ptr)
|
||||
{
|
||||
return OutParamRef<T>(ptr);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_RefPtr_h_
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
// Command line that builds these tests
|
||||
//
|
||||
// cp RefPtr.h test.cc && g++ -g -Wall -pedantic -DDEBUG -o test test.cc && ./test
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
struct Foo : public RefCounted<Foo>
|
||||
{
|
||||
Foo() : dead(false) { }
|
||||
~Foo() {
|
||||
MOZ_ASSERT(!dead);
|
||||
dead = true;
|
||||
numDestroyed++;
|
||||
}
|
||||
|
||||
bool dead;
|
||||
static int numDestroyed;
|
||||
};
|
||||
int Foo::numDestroyed;
|
||||
|
||||
struct Bar : public Foo { };
|
||||
|
||||
TemporaryRef<Foo>
|
||||
NewFoo()
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
return f.forget();
|
||||
}
|
||||
|
||||
TemporaryRef<Foo>
|
||||
NewBar()
|
||||
{
|
||||
RefPtr<Bar> b = new Bar();
|
||||
return b.forget();
|
||||
}
|
||||
|
||||
void
|
||||
GetNewFoo(Foo** f)
|
||||
{
|
||||
*f = new Bar();
|
||||
}
|
||||
|
||||
void
|
||||
GetPassedFoo(Foo** f)
|
||||
{}
|
||||
|
||||
void
|
||||
GetNewFoo(RefPtr<Foo>* f)
|
||||
{
|
||||
*f = new Bar();
|
||||
}
|
||||
|
||||
void
|
||||
GetPassedFoo(RefPtr<Foo>* f)
|
||||
{}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
// This should blow up
|
||||
// Foo* f = new Foo(); delete f;
|
||||
|
||||
MOZ_ASSERT(0 == Foo::numDestroyed);
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
MOZ_ASSERT(f->refCount() == 1);
|
||||
}
|
||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1 = NewFoo();
|
||||
RefPtr<Foo> f2(NewFoo());
|
||||
MOZ_ASSERT(1 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> b = NewBar();
|
||||
MOZ_ASSERT(3 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1;
|
||||
{
|
||||
f1 = new Foo();
|
||||
RefPtr<Foo> f2(f1);
|
||||
RefPtr<Foo> f3 = f2;
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(4 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(5 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
f.forget();
|
||||
MOZ_ASSERT(6 == Foo::numDestroyed);
|
||||
}
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetNewFoo(byRef(f));
|
||||
MOZ_ASSERT(7 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(8 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetPassedFoo(byRef(f));
|
||||
MOZ_ASSERT(8 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(9 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetNewFoo(&f);
|
||||
MOZ_ASSERT(10 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(11 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f = new Foo();
|
||||
GetPassedFoo(&f);
|
||||
MOZ_ASSERT(11 == Foo::numDestroyed);
|
||||
}
|
||||
MOZ_ASSERT(12 == Foo::numDestroyed);
|
||||
|
||||
{
|
||||
RefPtr<Foo> f1 = new Bar();
|
||||
}
|
||||
MOZ_ASSERT(13 == Foo::numDestroyed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
3
netwerk/cache/nsDiskCacheDeviceSQL.cpp
vendored
3
netwerk/cache/nsDiskCacheDeviceSQL.cpp
vendored
@ -1979,8 +1979,7 @@ nsOfflineCacheDevice::AddNamespace(const nsCString &clientID,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
LOG(("nsOfflineCacheDevice::AddNamespace [cid=%s, ns=%s, data=%s, type=%d]",
|
||||
PromiseFlatCString(clientID).get(),
|
||||
namespaceSpec.get(), data.get(), itemType));
|
||||
clientID.get(), namespaceSpec.get(), data.get(), itemType));
|
||||
|
||||
AutoResetStatement statement(mStatement_InsertNamespaceEntry);
|
||||
|
||||
|
@ -306,8 +306,7 @@ bool
|
||||
HttpChannelParent::RecvSetCacheTokenCachedCharset(const nsCString& charset)
|
||||
{
|
||||
if (mCacheDescriptor)
|
||||
mCacheDescriptor->SetMetaDataElement("charset",
|
||||
PromiseFlatCString(charset).get());
|
||||
mCacheDescriptor->SetMetaDataElement("charset", charset.get());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <android/log.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "nsXULAppAPI.h"
|
||||
#include <pthread.h>
|
||||
@ -104,6 +105,8 @@ AndroidBridge::Init(JNIEnv *jEnv,
|
||||
|
||||
mJNIEnv = nsnull;
|
||||
mThread = nsnull;
|
||||
mOpenedBitmapLibrary = false;
|
||||
mHasNativeBitmapAccess = false;
|
||||
|
||||
mGeckoAppShellClass = (jclass) jEnv->NewGlobalRef(jGeckoAppShellClass);
|
||||
|
||||
@ -858,3 +861,84 @@ AndroidBridge::ScanMedia(const nsAString& aFile, const nsACString& aMimeType)
|
||||
mJNIEnv->CallStaticVoidMethod(mGeckoAppShellClass, jScanMedia, jstrFile, jstrMimeTypes);
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::HasNativeBitmapAccess()
|
||||
{
|
||||
if (!mOpenedBitmapLibrary) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
bool
|
||||
AndroidBridge::ValidateBitmap(jobject bitmap, int width, int height)
|
||||
{
|
||||
// This structure is defined in Android API level 8's <android/bitmap.h>
|
||||
// Because we can't depend on this, we get the function pointers via dlsym
|
||||
// and define this struct ourselves.
|
||||
struct BitmapInfo {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t stride;
|
||||
uint32_t format;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
int err;
|
||||
struct BitmapInfo info = { 0, };
|
||||
|
||||
if ((err = AndroidBitmap_getInfo(JNI(), bitmap, &info)) != 0) {
|
||||
ALOG_BRIDGE("AndroidBitmap_getInfo failed! (error %d)", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.width != width || info.height != height)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void *
|
||||
AndroidBridge::LockBitmap(jobject bitmap)
|
||||
{
|
||||
int err;
|
||||
void *buf;
|
||||
|
||||
if ((err = AndroidBitmap_lockPixels(JNI(), bitmap, &buf)) != 0) {
|
||||
ALOG_BRIDGE("AndroidBitmap_lockPixels failed! (error %d)", err);
|
||||
buf = nsnull;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
AndroidBridge::UnlockBitmap(jobject bitmap)
|
||||
{
|
||||
int err;
|
||||
if ((err = AndroidBitmap_unlockPixels(JNI(), bitmap)) != 0)
|
||||
ALOG_BRIDGE("AndroidBitmap_unlockPixels failed! (error %d)", err);
|
||||
}
|
||||
|
||||
|
@ -245,6 +245,15 @@ public:
|
||||
|
||||
void ScanMedia(const nsAString& aFile, const nsACString& aMimeType);
|
||||
|
||||
// These next four functions are for native Bitmap access in Android 2.2+
|
||||
bool HasNativeBitmapAccess();
|
||||
|
||||
bool ValidateBitmap(jobject bitmap, int width, int height);
|
||||
|
||||
void *LockBitmap(jobject bitmap);
|
||||
|
||||
void UnlockBitmap(jobject bitmap);
|
||||
|
||||
protected:
|
||||
static AndroidBridge *sBridge;
|
||||
|
||||
@ -266,6 +275,9 @@ protected:
|
||||
|
||||
void EnsureJNIThread();
|
||||
|
||||
bool mOpenedBitmapLibrary;
|
||||
bool mHasNativeBitmapAccess;
|
||||
|
||||
// other things
|
||||
jmethodID jNotifyIME;
|
||||
jmethodID jNotifyIMEEnabled;
|
||||
@ -309,6 +321,11 @@ protected:
|
||||
jclass jEGLDisplayImplClass;
|
||||
jclass jEGLContextClass;
|
||||
jclass jEGL10Class;
|
||||
|
||||
// calls we've dlopened from libjnigraphics.so
|
||||
int (* AndroidBitmap_getInfo)(JNIEnv *env, jobject bitmap, void *info);
|
||||
int (* AndroidBitmap_lockPixels)(JNIEnv *env, jobject bitmap, void **buffer);
|
||||
int (* AndroidBitmap_unlockPixels)(JNIEnv *env, jobject bitmap);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -102,7 +102,9 @@ jmethodID AndroidAddress::jGetThoroughfareMethod;
|
||||
jclass AndroidGeckoSurfaceView::jGeckoSurfaceViewClass = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jBeginDrawingMethod = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jEndDrawingMethod = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jDraw2DMethod = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jDraw2DBitmapMethod = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jDraw2DBufferMethod = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jGetSoftwareDrawBitmapMethod = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jGetSoftwareDrawBufferMethod = 0;
|
||||
jmethodID AndroidGeckoSurfaceView::jGetHolderMethod = 0;
|
||||
|
||||
@ -170,9 +172,11 @@ AndroidGeckoSurfaceView::InitGeckoSurfaceViewClass(JNIEnv *jEnv)
|
||||
jGeckoSurfaceViewClass = getClassGlobalRef("org/mozilla/gecko/GeckoSurfaceView");
|
||||
|
||||
jBeginDrawingMethod = getMethod("beginDrawing", "()I");
|
||||
jGetSoftwareDrawBitmapMethod = getMethod("getSoftwareDrawBitmap", "()Landroid/graphics/Bitmap;");
|
||||
jGetSoftwareDrawBufferMethod = getMethod("getSoftwareDrawBuffer", "()Ljava/nio/ByteBuffer;");
|
||||
jEndDrawingMethod = getMethod("endDrawing", "()V");
|
||||
jDraw2DMethod = getMethod("draw2D", "(Ljava/nio/ByteBuffer;I)V");
|
||||
jDraw2DBitmapMethod = getMethod("draw2D", "(Landroid/graphics/Bitmap;II)V");
|
||||
jDraw2DBufferMethod = getMethod("draw2D", "(Ljava/nio/ByteBuffer;I)V");
|
||||
jGetHolderMethod = getMethod("getHolder", "()Landroid/view/SurfaceHolder;");
|
||||
}
|
||||
|
||||
@ -463,10 +467,22 @@ AndroidGeckoSurfaceView::EndDrawing()
|
||||
JNI()->CallVoidMethod(wrapped_obj, jEndDrawingMethod);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidGeckoSurfaceView::Draw2D(jobject bitmap, int width, int height)
|
||||
{
|
||||
JNI()->CallVoidMethod(wrapped_obj, jDraw2DBitmapMethod, bitmap, width, height);
|
||||
}
|
||||
|
||||
void
|
||||
AndroidGeckoSurfaceView::Draw2D(jobject buffer, int stride)
|
||||
{
|
||||
JNI()->CallVoidMethod(wrapped_obj, jDraw2DMethod, buffer, stride);
|
||||
JNI()->CallVoidMethod(wrapped_obj, jDraw2DBufferMethod, buffer, stride);
|
||||
}
|
||||
|
||||
jobject
|
||||
AndroidGeckoSurfaceView::GetSoftwareDrawBitmap()
|
||||
{
|
||||
return JNI()->CallObjectMethod(wrapped_obj, jGetSoftwareDrawBitmapMethod);
|
||||
}
|
||||
|
||||
jobject
|
||||
|
@ -167,8 +167,10 @@ public:
|
||||
};
|
||||
|
||||
int BeginDrawing();
|
||||
jobject GetSoftwareDrawBitmap();
|
||||
jobject GetSoftwareDrawBuffer();
|
||||
void EndDrawing();
|
||||
void Draw2D(jobject bitmap, int width, int height);
|
||||
void Draw2D(jobject buffer, int stride);
|
||||
|
||||
// must have a JNI local frame when calling this,
|
||||
@ -179,7 +181,9 @@ protected:
|
||||
static jclass jGeckoSurfaceViewClass;
|
||||
static jmethodID jBeginDrawingMethod;
|
||||
static jmethodID jEndDrawingMethod;
|
||||
static jmethodID jDraw2DMethod;
|
||||
static jmethodID jDraw2DBitmapMethod;
|
||||
static jmethodID jDraw2DBufferMethod;
|
||||
static jmethodID jGetSoftwareDrawBitmapMethod;
|
||||
static jmethodID jGetSoftwareDrawBufferMethod;
|
||||
static jmethodID jGetHolderMethod;
|
||||
};
|
||||
|
@ -987,27 +987,54 @@ nsWindow::OnDraw(AndroidGeckoEvent *ae)
|
||||
AndroidBridge::Bridge()->HideProgressDialogOnce();
|
||||
|
||||
if (GetLayerManager(nsnull)->GetBackendType() == LayerManager::LAYERS_BASIC) {
|
||||
jobject bytebuf = sview.GetSoftwareDrawBuffer();
|
||||
if (!bytebuf) {
|
||||
ALOG("no buffer to draw into - skipping draw");
|
||||
return;
|
||||
if (AndroidBridge::Bridge()->HasNativeBitmapAccess()) {
|
||||
jobject bitmap = sview.GetSoftwareDrawBitmap();
|
||||
if (!bitmap) {
|
||||
ALOG("no bitmap to draw into - skipping draw");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AndroidBridge::Bridge()->ValidateBitmap(bitmap, mBounds.width, mBounds.height))
|
||||
return;
|
||||
|
||||
void *buf = AndroidBridge::Bridge()->LockBitmap(bitmap);
|
||||
if (buf == nsnull) {
|
||||
ALOG("### Software drawing, but failed to lock bitmap.");
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> targetSurface =
|
||||
new gfxImageSurface((unsigned char *)buf,
|
||||
gfxIntSize(mBounds.width, mBounds.height),
|
||||
mBounds.width * 2,
|
||||
gfxASurface::ImageFormatRGB16_565);
|
||||
DrawTo(targetSurface);
|
||||
|
||||
AndroidBridge::Bridge()->UnlockBitmap(bitmap);
|
||||
sview.Draw2D(bitmap, mBounds.width, mBounds.height);
|
||||
} else {
|
||||
jobject bytebuf = sview.GetSoftwareDrawBuffer();
|
||||
if (!bytebuf) {
|
||||
ALOG("no buffer to draw into - skipping draw");
|
||||
return;
|
||||
}
|
||||
|
||||
void *buf = AndroidBridge::JNI()->GetDirectBufferAddress(bytebuf);
|
||||
int cap = AndroidBridge::JNI()->GetDirectBufferCapacity(bytebuf);
|
||||
if (!buf || cap != (mBounds.width * mBounds.height * 2)) {
|
||||
ALOG("### Software drawing, but unexpected buffer size %d expected %d (or no buffer %p)!", cap, mBounds.width * mBounds.height * 2, buf);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> targetSurface =
|
||||
new gfxImageSurface((unsigned char *)buf,
|
||||
gfxIntSize(mBounds.width, mBounds.height),
|
||||
mBounds.width * 2,
|
||||
gfxASurface::ImageFormatRGB16_565);
|
||||
DrawTo(targetSurface);
|
||||
|
||||
sview.Draw2D(bytebuf, mBounds.width * 2);
|
||||
}
|
||||
|
||||
void *buf = AndroidBridge::JNI()->GetDirectBufferAddress(bytebuf);
|
||||
int cap = AndroidBridge::JNI()->GetDirectBufferCapacity(bytebuf);
|
||||
if (!buf || cap != (mBounds.width * mBounds.height * 2)) {
|
||||
ALOG("### Software drawing, but unexpected buffer size %d expected %d (or no buffer %p)!", cap, mBounds.width * mBounds.height * 2, buf);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxImageSurface> targetSurface =
|
||||
new gfxImageSurface((unsigned char *)buf,
|
||||
gfxIntSize(mBounds.width, mBounds.height),
|
||||
mBounds.width * 2,
|
||||
gfxASurface::ImageFormatRGB16_565);
|
||||
|
||||
DrawTo(targetSurface);
|
||||
sview.Draw2D(bytebuf, mBounds.width * 2);
|
||||
} else {
|
||||
int drawType = sview.BeginDrawing();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user