mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 726930 - speed up tab thumbnails r=mfinkle
This commit is contained in:
parent
99a084de31
commit
585ae3af5b
@ -626,25 +626,7 @@ abstract public class GeckoApp
|
||||
int sh = forceBigSceenshot ? mSoftwareLayerClient.getHeight(): tab.getMinScreenshotHeight();
|
||||
int dw = forceBigSceenshot ? sw : tab.getThumbnailWidth();
|
||||
int dh = forceBigSceenshot ? sh : tab.getThumbnailHeight();
|
||||
try {
|
||||
JSONObject message = new JSONObject();
|
||||
message.put("tabID", tab.getId());
|
||||
|
||||
JSONObject source = new JSONObject();
|
||||
source.put("width", sw);
|
||||
source.put("height", sh);
|
||||
message.put("source", source);
|
||||
|
||||
JSONObject destination = new JSONObject();
|
||||
destination.put("width", dw);
|
||||
destination.put("height", dh);
|
||||
message.put("destination", destination);
|
||||
|
||||
String json = message.toString();
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Screenshot", json));
|
||||
} catch(JSONException jsonEx) {
|
||||
Log.w(LOGTAG, "Constructing the JSON data for Tab:Screenshot event failed", jsonEx);
|
||||
}
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), sw, sh, dw, dh));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -566,12 +566,14 @@ public class GeckoAppShell
|
||||
mInputConnection.notifyIMEChange(text, start, end, newEnd);
|
||||
}
|
||||
|
||||
public static void notifyScreenShot(ByteBuffer data, int tabId, int width, int height) {
|
||||
final Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
b.copyPixelsFromBuffer(data);
|
||||
final Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
public static void notifyScreenShot(final ByteBuffer data, final int tabId,
|
||||
final int width, final int height) {
|
||||
getHandler().post(new Runnable() {
|
||||
public void run() {
|
||||
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
|
||||
b.copyPixelsFromBuffer(data);
|
||||
freeDirectBuffer(data);
|
||||
final Tab tab = Tabs.getInstance().getTab(tabId);
|
||||
GeckoApp.mAppContext.processThumbnail(tab, b, null);
|
||||
}
|
||||
});
|
||||
|
@ -88,6 +88,7 @@ public class GeckoEvent {
|
||||
private static final int NETWORK_CHANGED = 22;
|
||||
private static final int PROXIMITY_EVENT = 23;
|
||||
private static final int ACTIVITY_RESUMING = 24;
|
||||
private static final int SCREENSHOT = 25;
|
||||
|
||||
public static final int IME_COMPOSITION_END = 0;
|
||||
public static final int IME_COMPOSITION_BEGIN = 1;
|
||||
@ -399,4 +400,13 @@ public class GeckoEvent {
|
||||
event.mCanBeMetered = canBeMetered;
|
||||
return event;
|
||||
}
|
||||
|
||||
public static GeckoEvent createScreenshotEvent(int tabId, int sw, int sh, int dw, int dh) {
|
||||
GeckoEvent event = new GeckoEvent(SCREENSHOT);
|
||||
event.mPoints = new Point[2];
|
||||
event.mPoints[0] = new Point(sw, sh);
|
||||
event.mPoints[1] = new Point(dw, dh);
|
||||
event.mMetaState = tabId;
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
@ -202,11 +202,12 @@ var BrowserApp = {
|
||||
|
||||
getBridge().setDrawMetadataProvider(MetadataProvider);
|
||||
|
||||
getBridge().browserApp = this;
|
||||
|
||||
Services.obs.addObserver(this, "Tab:Add", false);
|
||||
Services.obs.addObserver(this, "Tab:Load", false);
|
||||
Services.obs.addObserver(this, "Tab:Selected", false);
|
||||
Services.obs.addObserver(this, "Tab:Closed", false);
|
||||
Services.obs.addObserver(this, "Tab:Screenshot", false);
|
||||
Services.obs.addObserver(this, "Session:Back", false);
|
||||
Services.obs.addObserver(this, "Session:Forward", false);
|
||||
Services.obs.addObserver(this, "Session:Reload", false);
|
||||
@ -557,36 +558,6 @@ var BrowserApp = {
|
||||
this._tabs.splice(this._tabs.indexOf(aTab), 1);
|
||||
},
|
||||
|
||||
screenshotQueue: null,
|
||||
|
||||
screenshotTab: function screenshotTab(aData) {
|
||||
if (this.screenshotQueue == null) {
|
||||
this.screenShotQueue = [];
|
||||
this.doScreenshotTab(aData);
|
||||
} else {
|
||||
this.screenshotQueue.push(aData);
|
||||
}
|
||||
},
|
||||
|
||||
doNextScreenshot: function() {
|
||||
if (this.screenshotQueue == null || this.screenshotQueue.length == 0) {
|
||||
this.screenshotQueue = null;
|
||||
return;
|
||||
}
|
||||
let data = this.screenshotQueue.pop();
|
||||
if (data == null) {
|
||||
this.screenshotQueue = null;
|
||||
return;
|
||||
}
|
||||
this.doScreenshotTab(data);
|
||||
},
|
||||
|
||||
doScreenshotTab: function doScreenshotTab(aData) {
|
||||
let json = JSON.parse(aData);
|
||||
let tab = this.getTabForId(parseInt(json.tabID));
|
||||
tab.screenshot(json.source, json.destination);
|
||||
},
|
||||
|
||||
// Use this method to select a tab from JS. This method sends a message
|
||||
// to Java to select the tab in the Java UI (we'll get a Tab:Selected message
|
||||
// back from Java when that happens).
|
||||
@ -964,10 +935,6 @@ var BrowserApp = {
|
||||
this._handleTabSelected(this.getTabForId(parseInt(aData)));
|
||||
} else if (aTopic == "Tab:Closed") {
|
||||
this._handleTabClosed(this.getTabForId(parseInt(aData)));
|
||||
} else if (aTopic == "Tab:Screenshot") {
|
||||
this.screenshotTab(aData);
|
||||
} else if (aTopic == "Tab:Screenshot:Cancel") {
|
||||
this.screenshotQueue = null;
|
||||
} else if (aTopic == "Browser:Quit") {
|
||||
this.quit();
|
||||
} else if (aTopic == "SaveAs:PDF") {
|
||||
@ -1002,7 +969,16 @@ var BrowserApp = {
|
||||
delete this.defaultBrowserWidth;
|
||||
let width = Services.prefs.getIntPref("browser.viewport.desktopWidth");
|
||||
return this.defaultBrowserWidth = width;
|
||||
},
|
||||
|
||||
// nsIAndroidBrowserApp
|
||||
getWindowForTab: function(tabId) {
|
||||
let tab = this.getTabForId(tabId);
|
||||
if (!tab.browser)
|
||||
return null;
|
||||
return tab.browser.contentWindow;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var NativeWindow = {
|
||||
@ -1655,16 +1631,6 @@ Tab.prototype = {
|
||||
this.updateTransform();
|
||||
},
|
||||
|
||||
screenshot: function(aSrc, aDst) {
|
||||
if (!this.browser || !this.browser.contentWindow)
|
||||
return;
|
||||
|
||||
getBridge().takeScreenshot(this.browser.contentWindow, 0, 0, aSrc.width, aSrc.height, aDst.width, aDst.height, this.id);
|
||||
Services.tm.mainThread.dispatch(function() {
|
||||
BrowserApp.doNextScreenshot()
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
},
|
||||
|
||||
updateTransform: function() {
|
||||
let hasZoom = (Math.abs(this._viewport.zoom - 1.0) >= 1e-6);
|
||||
let x = this._viewport.offsetX + Math.round(-this.viewportExcess.x * this._viewport.zoom);
|
||||
|
@ -1967,8 +1967,27 @@ AndroidBridge::HideSurface(jobject surface)
|
||||
}
|
||||
|
||||
|
||||
/* void takeScreenshot (in nsIDOMWindow win, in PRInt32 srcX, in PRInt32 srcY, in PRInt32 srcW, in PRInt32 srcH, in PRInt32 dstX, in PRInt32 dstY, in PRInt32 dstW, in PRInt32 dstH, in AString color); */
|
||||
NS_IMETHODIMP nsAndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstW, PRInt32 dstH, PRInt32 tabId)
|
||||
/* attribute nsIAndroidBrowserApp browserApp; */
|
||||
NS_IMETHODIMP nsAndroidBridge::GetBrowserApp(nsIAndroidBrowserApp * *aBrowserApp)
|
||||
{
|
||||
if (nsAppShell::gAppShell)
|
||||
nsAppShell::gAppShell->GetBrowserApp(aBrowserApp);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsAndroidBridge::SetBrowserApp(nsIAndroidBrowserApp *aBrowserApp)
|
||||
{
|
||||
if (nsAppShell::gAppShell)
|
||||
nsAppShell::gAppShell->SetBrowserApp(aBrowserApp);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
__attribute__ ((visibility("default")))
|
||||
jobject JNICALL
|
||||
Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *jenv, jclass, jlong size);
|
||||
|
||||
|
||||
nsresult AndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstW, PRInt32 dstH, PRInt32 tabId)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryInterface(window);
|
||||
if (!win)
|
||||
@ -1989,22 +2008,23 @@ NS_IMETHODIMP nsAndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX
|
||||
nsPresContext::CSSPixelsToAppUnits(srcW),
|
||||
nsPresContext::CSSPixelsToAppUnits(srcH));
|
||||
|
||||
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(nsIntSize(dstW, dstH), gfxASurface::ImageFormatRGB16_565);
|
||||
JNIEnv* jenv = AndroidBridge::GetJNIEnv();
|
||||
if (!jenv)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 stride = dstW * 2;
|
||||
PRUint32 bufferSize = dstH * stride;
|
||||
|
||||
jobject buffer = Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(jenv, NULL, bufferSize);
|
||||
if (!buffer)
|
||||
return NS_OK;
|
||||
|
||||
void* data = jenv->GetDirectBufferAddress(buffer);
|
||||
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(static_cast<unsigned char*>(data), nsIntSize(dstW, dstH), stride, gfxASurface::ImageFormatRGB16_565);
|
||||
nsRefPtr<gfxContext> context = new gfxContext(surf);
|
||||
nsresult rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
AndroidBridge::Bridge()->NotifyScreenshot(surf->Data(), surf->GetDataSize(), tabId, dstW, dstH);
|
||||
AndroidBridge::AutoLocalJNIFrame jniFrame(jenv, 1);
|
||||
jenv->CallStaticVoidMethod(AndroidBridge::Bridge()->mGeckoAppShellClass, AndroidBridge::Bridge()->jNotifyScreenShot, buffer, tabId, dstW, dstH);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void AndroidBridge::NotifyScreenshot(unsigned char* data, int size, int tabId, int width, int height)
|
||||
{
|
||||
JNIEnv* jenv = GetJNIEnv();
|
||||
if (!jenv)
|
||||
return;
|
||||
AutoLocalJNIFrame jniFrame(jenv, 1);
|
||||
jobject buffer = jenv->NewDirectByteBuffer(data, size);
|
||||
if (!buffer)
|
||||
return;
|
||||
jenv->CallStaticVoidMethod(mGeckoAppShellClass, jNotifyScreenShot, buffer, tabId, width, height);
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ public:
|
||||
|
||||
static void NotifyIMEChange(const PRUnichar *aText, PRUint32 aTextLen, int aStart, int aEnd, int aNewEnd);
|
||||
|
||||
void NotifyScreenshot(unsigned char* data, int size, int tabId, int width, int height);
|
||||
nsresult TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstW, PRInt32 dstH, PRInt32 tabId);
|
||||
|
||||
void AcknowledgeEventSync();
|
||||
|
||||
|
@ -555,6 +555,11 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
|
||||
break;
|
||||
}
|
||||
|
||||
case SCREENSHOT: {
|
||||
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
|
||||
ReadPointArray(mPoints, jenv, jPoints, 2);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -570,6 +570,7 @@ public:
|
||||
NETWORK_CHANGED = 22,
|
||||
PROXIMITY_EVENT = 23,
|
||||
ACTIVITY_RESUMING = 24,
|
||||
SCREENSHOT = 25,
|
||||
dummy_java_enum_list_end
|
||||
};
|
||||
|
||||
|
@ -434,6 +434,23 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
|
||||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::SCREENSHOT: {
|
||||
if (!mBrowserApp)
|
||||
break;
|
||||
|
||||
AndroidBridge* bridge = AndroidBridge::Bridge();
|
||||
if (!bridge)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> domWindow;
|
||||
mBrowserApp->GetWindowForTab(curEvent->MetaState(), getter_AddRefs(domWindow));
|
||||
nsTArray<nsIntPoint> points = curEvent->Points();
|
||||
NS_ASSERTION(points.Length() != 2, "Screenshot event does not have enough coordinates");
|
||||
if (domWindow)
|
||||
bridge->TakeScreenshot(domWindow, 0, 0, points[0].x, points[0].y, points[1].x, points[1].y, curEvent->MetaState());
|
||||
break;
|
||||
}
|
||||
|
||||
case AndroidGeckoEvent::VIEWPORT:
|
||||
case AndroidGeckoEvent::BROADCAST: {
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsInterfaceHashtable.h"
|
||||
#include "nsIAndroidBridge.h"
|
||||
|
||||
namespace mozilla {
|
||||
class AndroidGeckoEvent;
|
||||
@ -84,6 +85,14 @@ public:
|
||||
void NotifyObservers(nsISupports *aSupports, const char *aTopic, const PRUnichar *aData);
|
||||
void ResendLastResizeEvent(nsWindow* aDest);
|
||||
|
||||
void SetBrowserApp(nsIAndroidBrowserApp* aBrowserApp) {
|
||||
mBrowserApp = aBrowserApp;
|
||||
}
|
||||
|
||||
void GetBrowserApp(nsIAndroidBrowserApp* *aBrowserApp) {
|
||||
*aBrowserApp = mBrowserApp;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void ScheduleNativeEventCallback();
|
||||
virtual ~nsAppShell();
|
||||
@ -99,6 +108,8 @@ protected:
|
||||
|
||||
mozilla::AndroidGeckoEvent *PopNextEvent();
|
||||
mozilla::AndroidGeckoEvent *PeekNextEvent();
|
||||
|
||||
nsCOMPtr<nsIAndroidBrowserApp> mBrowserApp;
|
||||
};
|
||||
|
||||
#endif // nsAppShell_h__
|
||||
|
@ -12,11 +12,15 @@ interface nsIAndroidDrawMetadataProvider : nsISupports {
|
||||
boolean paintingSuppressed();
|
||||
};
|
||||
|
||||
[scriptable, uuid(d10377b4-1c90-493a-a532-63cb3f16ee2b)]
|
||||
interface nsIAndroidBrowserApp : nsISupports {
|
||||
nsIDOMWindow getWindowForTab(in PRInt32 tabId);
|
||||
};
|
||||
|
||||
[scriptable, uuid(7dd8441a-4f38-49b2-bd90-da69d02a96cf)]
|
||||
interface nsIAndroidBridge : nsISupports
|
||||
{
|
||||
AString handleGeckoMessage(in AString message);
|
||||
void setDrawMetadataProvider(in nsIAndroidDrawMetadataProvider provider);
|
||||
void takeScreenshot(in nsIDOMWindow win, in PRInt32 srcX, in PRInt32 srcY, in PRInt32 srcW, in PRInt32 srcH,
|
||||
in PRInt32 dstW, in PRInt32 dstH, in PRInt32 tabId);
|
||||
attribute nsIAndroidBrowserApp browserApp;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user