Back out bug 760342 for Windows build error, bug 755070 for Android crashes, and bug 760458 because it depends on 755070

This commit is contained in:
Matt Brubeck 2012-06-01 17:45:02 -07:00
parent 704577802d
commit e62fcc8acf
17 changed files with 138 additions and 338 deletions

View File

@ -256,14 +256,6 @@ void MessageLoop::PostNonNestableDelayedTask(
PostTask_Helper(from_here, task, delay_ms, false);
}
void MessageLoop::PostIdleTask(
const tracked_objects::Location& from_here, Task* task) {
DCHECK(current() == this);
task->SetBirthPlace(from_here);
PendingTask pending_task(task, false);
deferred_non_nestable_work_queue_.push(pending_task);
}
// Possibly called on a background thread!
void MessageLoop::PostTask_Helper(
const tracked_objects::Location& from_here, Task* task, int delay_ms,

View File

@ -121,10 +121,6 @@ public:
void PostNonNestableDelayedTask(
const tracked_objects::Location& from_here, Task* task, int delay_ms);
// PostIdleTask is not thread safe and should be called on this thread
void PostIdleTask(
const tracked_objects::Location& from_here, Task* task);
// A variant on PostTask that deletes the given object. This is useful
// if the object needs to live until the next run of the MessageLoop (for
// example, deleting a RenderProcessHost from within an IPC callback is not

View File

@ -142,23 +142,21 @@ class HashTable : private AllocPolicy
protected:
friend class HashTable;
Range(Entry *c, Entry *e) : cur(c), end(e), validEntry(true) {
Range(Entry *c, Entry *e) : cur(c), end(e) {
while (cur < end && !cur->isLive())
++cur;
}
Entry *cur, *end;
DebugOnly<bool> validEntry;
public:
Range() : cur(NULL), end(NULL), validEntry(false) {}
Range() : cur(NULL), end(NULL) {}
bool empty() const {
return cur == end;
}
T &front() const {
JS_ASSERT(validEntry);
JS_ASSERT(!empty());
return cur->t;
}
@ -167,7 +165,6 @@ class HashTable : private AllocPolicy
JS_ASSERT(!empty());
while (++cur < end && !cur->isLive())
continue;
validEntry = true;
}
};
@ -208,7 +205,6 @@ class HashTable : private AllocPolicy
void removeFront() {
table.remove(*this->cur);
removed = true;
this->validEntry = false;
}
/*
@ -225,7 +221,6 @@ class HashTable : private AllocPolicy
table.remove(*this->cur);
table.add(l, e);
added = true;
this->validEntry = false;
}
void rekeyFront(const Key &k) {

View File

@ -187,6 +187,7 @@ class WeakMap : public HashMap<Key, Value, HashPolicy, RuntimeAllocPolicy>, publ
markedAny = true;
e.rekeyFront(k);
}
JS_ASSERT_IF(keyIsMarked, gc::IsMarked(&e.front().value));
}
return markedAny;
}

View File

@ -688,7 +688,7 @@ abstract public class GeckoApp
int dw = tab.getThumbnailWidth();
int dh = tab.getThumbnailHeight();
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), 0, 0, 0, 0, 0, 0, dw, dh, dw, dh, GeckoAppShell.SCREENSHOT_THUMBNAIL, tab.getThumbnailBuffer()));
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(), 0, 0, 0, 0, 0, 0, dw, dh, GeckoAppShell.SCREENSHOT_THUMBNAIL));
}
}

View File

@ -15,7 +15,6 @@ import org.mozilla.gecko.gfx.ScreenshotLayer;
import org.mozilla.gecko.FloatUtils;
import org.mozilla.gecko.gfx.ImmutableViewportMetrics;
import org.mozilla.gecko.gfx.ViewportMetrics;
import org.mozilla.gecko.gfx.RectUtils;
import java.io.*;
import java.lang.reflect.*;
@ -84,7 +83,8 @@ public class GeckoAppShell
public static final String SHORTCUT_TYPE_BOOKMARK = "bookmark";
static public final int SCREENSHOT_THUMBNAIL = 0;
static public final int SCREENSHOT_CHECKERBOARD = 1;
static public final int SCREENSHOT_WHOLE_PAGE = 1;
static public final int SCREENSHOT_UPDATE = 2;
static public final int RESTORE_NONE = 0;
static public final int RESTORE_OOM = 1;
@ -98,6 +98,11 @@ public class GeckoAppShell
private static Boolean sNSSLibsLoaded = false;
private static Boolean sLibsSetup = false;
private static File sGREDir = null;
private static RectF sCheckerboardPageRect;
private static float sLastCheckerboardWidthRatio, sLastCheckerboardHeightRatio;
private static RepaintRunnable sRepaintRunnable = new RepaintRunnable();
static private int sMaxTextureSize = 0;
private static Map<String, CopyOnWriteArrayList<GeckoEventListener>> mEventListeners
= new HashMap<String, CopyOnWriteArrayList<GeckoEventListener>>();
@ -123,6 +128,8 @@ public class GeckoAppShell
private static Handler sGeckoHandler;
private static boolean sDisableScreenshot = false;
/* The Android-side API: API methods that Android calls */
// Initialization methods
@ -528,7 +535,42 @@ public class GeckoAppShell
// Called by AndroidBridge using JNI
public static void notifyScreenShot(final ByteBuffer data, final int tabId, final int x, final int y,
final int width, final int height, final int token) {
ScreenshotHandler.notifyScreenShot(data, tabId, x, y, width, height, token);
getHandler().post(new Runnable() {
public void run() {
try {
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null)
return;
if (!Tabs.getInstance().isSelectedTab(tab) && SCREENSHOT_THUMBNAIL != token)
return;
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
b.copyPixelsFromBuffer(data);
switch (token) {
case SCREENSHOT_WHOLE_PAGE:
GeckoApp.mAppContext.getLayerController()
.getView().getRenderer()
.setCheckerboardBitmap(b, sCheckerboardPageRect);
break;
case SCREENSHOT_UPDATE:
GeckoApp.mAppContext.getLayerController().getView().getRenderer().
updateCheckerboardBitmap(
b, sLastCheckerboardWidthRatio * x,
sLastCheckerboardHeightRatio * y,
sLastCheckerboardWidthRatio * width,
sLastCheckerboardHeightRatio * height,
sCheckerboardPageRect);
break;
case SCREENSHOT_THUMBNAIL:
GeckoApp.mAppContext.processThumbnail(tab, b, null);
break;
}
} finally {
freeDirectBuffer(data);
}
}
});
}
private static CountDownLatch sGeckoPendingAcks = null;
@ -2094,26 +2136,6 @@ public class GeckoAppShell
if (!GeckoApp.mAppContext.showFilePicker(aMimeType, new AsyncResultHandler(id)))
GeckoAppShell.notifyFilePickerResult("", id);
}
public static void screenshotWholePage(Tab tab) {
ScreenshotHandler.screenshotWholePage(tab);
}
// Called by AndroidBridge using JNI
public static void notifyPaintedRect(float top, float left, float bottom, float right) {
ScreenshotHandler.notifyPaintedRect(top, left, bottom, right);
}
}
class ScreenshotHandler {
private static Queue<PendingScreenshot> sPendingScreenshots = new ArrayDeque<PendingScreenshot>();
private static RectF sCheckerboardPageRect;
private static float sLastCheckerboardWidthRatio, sLastCheckerboardHeightRatio;
private static RepaintRunnable sRepaintRunnable = new RepaintRunnable();
private static int sMaxTextureSize = 0;
private static final String LOGTAG = "GeckoScreenshot";
private static boolean sDisableScreenshot = false;
private static ByteBuffer sWholePageScreenshotBuffer;
private static int sCheckerboardBufferWidth, sCheckerboardBufferHeight;
static class RepaintRunnable implements Runnable {
private boolean mIsRepaintRunnablePosted = false;
@ -2136,40 +2158,25 @@ class ScreenshotHandler {
mIsRepaintRunnablePosted = false;
}
Tab tab = Tabs.getInstance().getSelectedTab();
ImmutableViewportMetrics viewport = GeckoApp.mAppContext.getLayerController().getViewportMetrics();
if (RectUtils.fuzzyEquals(sCheckerboardPageRect, viewport.getCssPageRect())) {
float width = right - left;
float height = bottom - top;
scheduleCheckerboardScreenshotEvent(tab.getId(),
(int)left, (int)top, (int)width, (int)height,
(int)(sLastCheckerboardWidthRatio * left),
(int)(sLastCheckerboardHeightRatio * top),
(int)(sLastCheckerboardWidthRatio * width),
(int)(sLastCheckerboardHeightRatio * height),
sCheckerboardBufferWidth, sCheckerboardBufferHeight);
} else {
GeckoAppShell.screenshotWholePage(tab);
}
GeckoAppShell.screenshotWholePage(tab);
}
void addRectToRepaint(float top, float left, float bottom, float right) {
synchronized(this) {
ImmutableViewportMetrics viewport = GeckoApp.mAppContext.getLayerController().getViewportMetrics();
mDirtyTop = Math.max(sCheckerboardPageRect.top, Math.min(top, mDirtyTop));
mDirtyLeft = Math.max(sCheckerboardPageRect.left, Math.min(left, mDirtyLeft));
mDirtyBottom = Math.min(sCheckerboardPageRect.bottom, Math.max(bottom, mDirtyBottom));
mDirtyRight = Math.min(sCheckerboardPageRect.right, Math.max(right, mDirtyRight));
mDirtyTop = Math.min(top, mDirtyTop);
mDirtyLeft = Math.min(left, mDirtyLeft);
mDirtyBottom = Math.max(bottom, mDirtyBottom);
mDirtyRight = Math.max(right, mDirtyRight);
if (!mIsRepaintRunnablePosted) {
GeckoAppShell.getHandler().postDelayed(this, 5000);
getHandler().postDelayed(this, 5000);
mIsRepaintRunnablePosted = true;
}
}
}
}
// Called by AndroidBridge using JNI
public static void notifyPaintedRect(float top, float left, float bottom, float right) {
sRepaintRunnable.addRectToRepaint(top, left, bottom, right);
}
@ -2196,9 +2203,7 @@ class ScreenshotHandler {
sMaxTextureSize = maxTextureSize[0];
if (sMaxTextureSize == 0)
return;
sWholePageScreenshotBuffer = GeckoAppShell.allocateDirectBuffer(ScreenshotLayer.getMaxNumPixels() * 2 /* 16 bpp */);
}
ImmutableViewportMetrics viewport = GeckoApp.mAppContext.getLayerController().getViewportMetrics();
Log.i(LOGTAG, "Taking whole-screen screenshot, viewport: " + viewport);
// source width and height to screenshot
@ -2219,96 +2224,14 @@ class ScreenshotHandler {
int dy = 0;
int dw = clamp(minTextureSize, idealDstWidth, sMaxTextureSize);
int dh = maxPixels / dw;
sCheckerboardBufferWidth = dw;
sCheckerboardBufferHeight = dh;
sLastCheckerboardWidthRatio = dw / sw;
sLastCheckerboardHeightRatio = dh / sh;
sCheckerboardPageRect = viewport.getCssPageRect();
scheduleCheckerboardScreenshotEvent(tab.getId(), (int)sx, (int)sy, (int)sw, (int)sh, dx, dy, dw, dh, dw, dh);
}
static void scheduleCheckerboardScreenshotEvent(int tabId, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int bw, int bh) {
float totalSize = sw * sh;
int numSlices = (int) Math.ceil(totalSize / 100000);
int srcSliceSize = (int) Math.ceil(sh / numSlices);
int dstSliceSize = (int) Math.ceil(dh / numSlices);
for (int i = 0; i < numSlices; i++) {
GeckoEvent event =
GeckoEvent.createScreenshotEvent(tabId,
sx, sy + srcSliceSize * i, sw, srcSliceSize,
dx, dy + dstSliceSize * i, dw, dstSliceSize, bw, bh,
GeckoAppShell.SCREENSHOT_CHECKERBOARD,
sWholePageScreenshotBuffer);
synchronized(sPendingScreenshots) {
sPendingScreenshots.add(new PendingScreenshot(tabId, event));
if (sPendingScreenshots.size() == 1)
sendNextEventToGecko();
}
}
}
static void sendNextEventToGecko() {
synchronized(sPendingScreenshots) {
if (sPendingScreenshots.isEmpty())
return;
GeckoAppShell.sendEventToGecko(sPendingScreenshots.element().getEvent());
}
}
static class PendingScreenshot {
private final GeckoEvent mEvent;
private final int mTabId;
PendingScreenshot(int tabId, GeckoEvent event) {
mTabId = tabId;
mEvent = event;
}
GeckoEvent getEvent() {
return mEvent;
}
}
public static void notifyScreenShot(final ByteBuffer data, final int tabId, final int x, final int y,
final int width, final int height, final int token) {
GeckoAppShell.getHandler().post(new Runnable() {
public void run() {
final Tab tab = Tabs.getInstance().getTab(tabId);
if (tab == null) {
if (token == GeckoAppShell.SCREENSHOT_CHECKERBOARD) {
synchronized(sPendingScreenshots) {
sPendingScreenshots.remove();
sendNextEventToGecko();
}
}
return;
}
switch (token) {
case GeckoAppShell.SCREENSHOT_CHECKERBOARD:
{
GeckoApp.mAppContext.getLayerController()
.getView().getRenderer()
.setCheckerboardBitmap(data, width, height, sCheckerboardPageRect);
synchronized(sPendingScreenshots) {
sPendingScreenshots.remove();
sendNextEventToGecko();
}
break;
}
case GeckoAppShell.SCREENSHOT_THUMBNAIL:
{
if (Tabs.getInstance().isSelectedTab(tab)) {
Bitmap b = tab.getThumbnailBitmap();
b.copyPixelsFromBuffer(data);
GeckoApp.mAppContext.processThumbnail(tab, b, null);
}
break;
}
}
}
});
GeckoAppShell.sendEventToGecko(GeckoEvent.createScreenshotEvent(tab.getId(),
(int)FloatMath.ceil(sx), (int)FloatMath.ceil(sy),
(int)FloatMath.floor(sw), (int)FloatMath.floor(sh),
dx, dy, dw, dh, GeckoAppShell.SCREENSHOT_WHOLE_PAGE));
}
}

View File

@ -23,7 +23,6 @@ import android.text.format.Time;
import android.os.SystemClock;
import java.lang.Math;
import java.lang.System;
import java.nio.ByteBuffer;
import android.util.Log;
@ -117,8 +116,6 @@ public class GeckoEvent {
public short mScreenOrientation;
public ByteBuffer mBuffer;
private GeckoEvent(int evType) {
mType = evType;
}
@ -459,17 +456,15 @@ public class GeckoEvent {
return event;
}
public static GeckoEvent createScreenshotEvent(int tabId, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int bw, int bh, int token, ByteBuffer buffer) {
public static GeckoEvent createScreenshotEvent(int tabId, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int token) {
GeckoEvent event = new GeckoEvent(SCREENSHOT);
event.mPoints = new Point[5];
event.mPoints = new Point[4];
event.mPoints[0] = new Point(sx, sy);
event.mPoints[1] = new Point(sw, sh);
event.mPoints[2] = new Point(dx, dy);
event.mPoints[3] = new Point(dw, dh);
event.mPoints[4] = new Point(bw, bh);
event.mMetaState = tabId;
event.mFlags = token;
event.mBuffer = buffer;
return event;
}

View File

@ -21,7 +21,6 @@ import org.json.JSONObject;
import org.mozilla.gecko.db.BrowserDB;
import org.mozilla.gecko.gfx.Layer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
@ -65,8 +64,6 @@ public final class Tab {
private ContentObserver mContentObserver;
private int mCheckerboardColor = Color.WHITE;
private int mState;
private ByteBuffer mThumbnailBuffer;
private Bitmap mThumbnailBitmap;
public static final int STATE_DELAYED = 0;
public static final int STATE_LOADING = 1;
@ -141,31 +138,6 @@ public final class Tab {
return mThumbnail;
}
synchronized public ByteBuffer getThumbnailBuffer() {
int capacity = getThumbnailWidth() * getThumbnailHeight() * 2 /* 16 bpp */;
if (mThumbnailBuffer != null && mThumbnailBuffer.capacity() == capacity)
return mThumbnailBuffer;
if (mThumbnailBuffer != null)
GeckoAppShell.freeDirectBuffer(mThumbnailBuffer); // not calling freeBuffer() because it would deadlock
return mThumbnailBuffer = GeckoAppShell.allocateDirectBuffer(capacity);
}
public Bitmap getThumbnailBitmap() {
if (mThumbnailBitmap != null)
return mThumbnailBitmap;
return mThumbnailBitmap = Bitmap.createBitmap(getThumbnailWidth(), getThumbnailHeight(), Bitmap.Config.RGB_565);
}
public void finalize() {
freeBuffer();
}
synchronized void freeBuffer() {
if (mThumbnailBuffer != null)
GeckoAppShell.freeDirectBuffer(mThumbnailBuffer);
mThumbnailBuffer = null;
}
float getDensity() {
if (sDensity == 0.0f) {
sDensity = GeckoApp.mAppContext.getDisplayMetrics().density;
@ -187,10 +159,13 @@ public final class Tab {
public void run() {
if (b != null) {
try {
if (mState == Tab.STATE_SUCCESS)
saveThumbnailToDB(new BitmapDrawable(b));
Bitmap bitmap = Bitmap.createScaledBitmap(b, getThumbnailWidth(), getThumbnailHeight(), false);
mThumbnail = new BitmapDrawable(b);
if (mState == Tab.STATE_SUCCESS)
saveThumbnailToDB(new BitmapDrawable(bitmap));
mThumbnail = new BitmapDrawable(bitmap);
b.recycle();
} catch (OutOfMemoryError oom) {
Log.e(LOGTAG, "Unable to create/scale bitmap", oom);
mThumbnail = null;

View File

@ -76,10 +76,8 @@ public class Tabs implements GeckoEventListener {
public void removeTab(int id) {
if (tabs.containsKey(id)) {
Tab tab = getTab(id);
order.remove(tab);
order.remove(getTab(id));
tabs.remove(id);
tab.freeBuffer();
Log.i(LOGTAG, "Removed a tab with id: " + id);
}
}

View File

@ -71,11 +71,5 @@ public class IntSize {
public IntSize nextPowerOfTwo() {
return new IntSize(nextPowerOfTwo(width), nextPowerOfTwo(height));
}
public static boolean isPowerOfTwo(int value) {
if (value == 0)
return false;
return (value & (value - 1)) == 0;
}
}

View File

@ -134,8 +134,8 @@ public class LayerRenderer implements GLSurfaceView.Renderer {
" gl_FragColor = texture2D(sTexture, vTexCoord);\n" +
"}\n";
public void setCheckerboardBitmap(ByteBuffer data, int width, int height, RectF pageRect) {
mCheckerboardLayer.setBitmap(data, width, height);
public void setCheckerboardBitmap(Bitmap bitmap, RectF pageRect) {
mCheckerboardLayer.setBitmap(bitmap);
mCheckerboardLayer.beginTransaction();
try {
mCheckerboardLayer.setPosition(RectUtils.round(pageRect));

View File

@ -35,7 +35,6 @@ public class ScreenshotLayer extends SingleTileLayer {
private IntSize mImageSize;
// Whether we have an up-to-date image to draw
private boolean mHasImage;
private static String LOGTAG = "GeckoScreenshot";
public static int getMaxNumPixels() {
return SCREENSHOT_SIZE_LIMIT;
@ -45,19 +44,6 @@ public class ScreenshotLayer extends SingleTileLayer {
mHasImage = false;
}
void setBitmap(ByteBuffer data, int width, int height) {
mImageSize = new IntSize(width, height);
if (IntSize.isPowerOfTwo(width) && IntSize.isPowerOfTwo(height)) {
mBufferSize = mImageSize;
mHasImage = true;
mImage.setBitmap(data, width, height, CairoImage.FORMAT_RGB16_565);
} else {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
b.copyPixelsFromBuffer(data);
setBitmap(b);
}
}
void setBitmap(Bitmap bitmap) {
mImageSize = new IntSize(bitmap.getWidth(), bitmap.getHeight());
int width = IntSize.nextPowerOfTwo(bitmap.getWidth());
@ -130,17 +116,7 @@ public class ScreenshotLayer extends SingleTileLayer {
}
}
void copyBuffer(ByteBuffer src, ByteBuffer dst, int size) {
dst.asIntBuffer().put(src.asIntBuffer());
}
synchronized void setBitmap(ByteBuffer data, int width, int height, int format) {
mSize = new IntSize(width, height);
mFormat = format;
copyBuffer(data, mBuffer, width * height * 2);
}
synchronized void setBitmap(Bitmap bitmap, int width, int height, int format) {
void setBitmap(Bitmap bitmap, int width, int height, int format) {
Bitmap tmp;
mSize = new IntSize(width, height);
mFormat = format;
@ -162,10 +138,10 @@ public class ScreenshotLayer extends SingleTileLayer {
}
@Override
synchronized public ByteBuffer getBuffer() { return mBuffer; }
public ByteBuffer getBuffer() { return mBuffer; }
@Override
synchronized public IntSize getSize() { return mSize; }
public IntSize getSize() { return mSize; }
@Override
synchronized public int getFormat() { return mFormat; }
public int getFormat() { return mFormat; }
}
}

View File

@ -29,8 +29,6 @@
#include "nsIDocShell.h"
#include "nsPIDOMWindow.h"
#include "mozilla/dom/ScreenOrientation.h"
#include "nsIDOMWindowUtils.h"
#include "nsIDOMClientRect.h"
#ifdef DEBUG
#define ALOG_BRIDGE(args...) ALOG(args)
@ -2350,33 +2348,36 @@ jobject JNICALL
Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(JNIEnv *env, jclass, jlong size);
nsresult AndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstX, PRInt32 dstY, PRInt32 dstW, PRInt32 dstH, PRInt32 bufW, PRInt32 bufH, PRInt32 tabId, PRInt32 token, jobject buffer)
nsresult AndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstW, PRInt32 dstH, PRInt32 tabId, float scale, PRInt32 token)
{
nsresult rv;
float scale = 1.0;
if (!buffer)
return NS_OK;
// take a screenshot, as wide as possible, proportional to the destination size
if (!srcW && !srcH) {
nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window);
if (!utils)
return NS_ERROR_FAILURE;
nsCOMPtr<nsIDOMClientRect> rect;
rv = utils->GetRootBounds(getter_AddRefs(rect));
nsCOMPtr<nsIDOMDocument> doc;
rv = window->GetDocument(getter_AddRefs(doc));
NS_ENSURE_SUCCESS(rv, rv);
if (!rect)
if (!doc)
return NS_ERROR_FAILURE;
float left, top, width, height;
rect->GetLeft(&left);
rect->GetTop(&top);
rect->GetWidth(&width);
rect->GetHeight(&height);
nsCOMPtr<nsIDOMElement> docElement;
rv = doc->GetDocumentElement(getter_AddRefs(docElement));
NS_ENSURE_SUCCESS(rv, rv);
if (!docElement)
return NS_ERROR_FAILURE;
if (width == 0 || height == 0)
PRInt32 viewportHeight;
PRInt32 pageWidth;
PRInt32 pageHeight;
window->GetInnerHeight(&viewportHeight);
docElement->GetScrollWidth(&pageWidth);
docElement->GetScrollHeight(&pageHeight);
// use the page or viewport dimensions, whichever is larger
PRInt32 width = pageWidth;
PRInt32 height = viewportHeight > pageHeight ? viewportHeight : pageHeight;
if (!width || !height)
return NS_ERROR_FAILURE;
float aspectRatio = ((float) dstW) / dstH;
@ -2387,9 +2388,6 @@ nsresult AndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt
srcW = height * aspectRatio;
srcH = height;
}
srcX = left;
srcY = top;
}
JNIEnv* env = GetJNIEnv();
@ -2417,17 +2415,21 @@ nsresult AndroidBridge::TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt
nsPresContext::CSSPixelsToAppUnits(srcW / scale),
nsPresContext::CSSPixelsToAppUnits(srcH / scale));
PRUint32 stride = bufW * 2 /* 16 bpp */;
PRUint32 stride = dstW * 2;
PRUint32 bufferSize = dstH * stride;
jobject buffer = Java_org_mozilla_gecko_GeckoAppShell_allocateDirectBuffer(env, NULL, bufferSize);
if (!buffer)
return NS_OK;
void* data = env->GetDirectBufferAddress(buffer);
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(static_cast<unsigned char*>(data), nsIntSize(bufW, bufH), stride, gfxASurface::ImageFormatRGB16_565);
memset(data, 0, bufferSize);
nsRefPtr<gfxImageSurface> surf = new gfxImageSurface(static_cast<unsigned char*>(data), nsIntSize(dstW, dstH), stride, gfxASurface::ImageFormatRGB16_565);
nsRefPtr<gfxContext> context = new gfxContext(surf);
gfxPoint pt(dstX, dstY);
context->Translate(pt);
context->Scale(scale * dstW / srcW, scale * dstH / srcH);
rv = presShell->RenderDocument(r, renderDocFlags, bgColor, context);
NS_ENSURE_SUCCESS(rv, rv);
env->CallStaticVoidMethod(AndroidBridge::Bridge()->mGeckoAppShellClass, AndroidBridge::Bridge()->jNotifyScreenShot, buffer, tabId, srcX * dstW / srcW , srcY * dstH / srcH, bufW, bufH, token);
env->CallStaticVoidMethod(AndroidBridge::Bridge()->mGeckoAppShellClass, AndroidBridge::Bridge()->jNotifyScreenShot, buffer, tabId, srcX * dstW / srcW , srcY * dstH / srcH, dstW, dstH, token);
return NS_OK;
}

View File

@ -155,7 +155,7 @@ public:
SCREENSHOT_UPDATE = 2
};
nsresult TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstY, PRInt32 dstX, PRInt32 dstW, PRInt32 dstH, PRInt32 bufW, PRInt32 bufH, PRInt32 tabId, PRInt32 token, jobject buffer);
nsresult TakeScreenshot(nsIDOMWindow *window, PRInt32 srcX, PRInt32 srcY, PRInt32 srcW, PRInt32 srcH, PRInt32 dstW, PRInt32 dstH, PRInt32 tabId, float scale, PRInt32 token);
static void NotifyPaintedRect(float top, float left, float bottom, float right);

View File

@ -42,7 +42,6 @@ jfieldID AndroidGeckoEvent::jLocationField = 0;
jfieldID AndroidGeckoEvent::jBandwidthField = 0;
jfieldID AndroidGeckoEvent::jCanBeMeteredField = 0;
jfieldID AndroidGeckoEvent::jScreenOrientationField = 0;
jfieldID AndroidGeckoEvent::jByteBufferField = 0;
jclass AndroidPoint::jPointClass = 0;
jfieldID AndroidPoint::jXField = 0;
@ -104,12 +103,6 @@ jmethodID AndroidGeckoSurfaceView::jGetHolderMethod = 0;
#define getMethod(fname, ftype) \
((jmethodID) jEnv->GetMethodID(jClass, fname, ftype))
RefCountedJavaObject::~RefCountedJavaObject() {
if (mObject)
GetJNIForThread()->DeleteGlobalRef(mObject);
mObject = NULL;
}
void
mozilla::InitAndroidJavaWrappers(JNIEnv *jEnv)
{
@ -161,7 +154,6 @@ AndroidGeckoEvent::InitGeckoEventClass(JNIEnv *jEnv)
jBandwidthField = getField("mBandwidth", "D");
jCanBeMeteredField = getField("mCanBeMetered", "Z");
jScreenOrientationField = getField("mScreenOrientation", "S");
jByteBufferField = getField("mBuffer", "Ljava/nio/ByteBuffer;");
}
void
@ -506,8 +498,7 @@ AndroidGeckoEvent::Init(JNIEnv *jenv, jobject jobj)
case SCREENSHOT: {
mMetaState = jenv->GetIntField(jobj, jMetaStateField);
mFlags = jenv->GetIntField(jobj, jFlagsField);
ReadPointArray(mPoints, jenv, jPoints, 5);
mByteBuffer = new RefCountedJavaObject(jenv, jenv->GetObjectField(jobj, jByteBufferField));
ReadPointArray(mPoints, jenv, jPoints, 4);
break;
}

View File

@ -41,27 +41,6 @@ void InitAndroidJavaWrappers(JNIEnv *jEnv);
* handle it.
*/
class RefCountedJavaObject {
public:
RefCountedJavaObject(JNIEnv* env, jobject obj) : mObject(env->NewGlobalRef(obj)) {}
~RefCountedJavaObject();
PRInt32 AddRef() { return ++mRefCnt; }
PRInt32 Release() {
PRInt32 refcnt = --mRefCnt;
if (refcnt == 0)
delete this;
return refcnt;
}
jobject GetObject() { return mObject; }
private:
PRInt32 mRefCnt;
jobject mObject;
};
class WrappedJavaObject {
public:
WrappedJavaObject() :
@ -597,7 +576,6 @@ public:
double Bandwidth() { return mBandwidth; }
bool CanBeMetered() { return mCanBeMetered; }
short ScreenOrientation() { return mScreenOrientation; }
RefCountedJavaObject* ByteBuffer() { return mByteBuffer; }
protected:
int mAction;
@ -622,7 +600,6 @@ protected:
double mBandwidth;
bool mCanBeMetered;
short mScreenOrientation;
nsRefPtr<RefCountedJavaObject> mByteBuffer;
void ReadIntArray(nsTArray<int> &aVals,
JNIEnv *jenv,
@ -676,7 +653,6 @@ protected:
static jfieldID jCanBeMeteredField;
static jfieldID jScreenOrientationField;
static jfieldID jByteBufferField;
public:
enum {

View File

@ -6,8 +6,6 @@
// Make sure the order of included headers
#include "base/basictypes.h"
#include "nspr/prtypes.h"
#include "base/message_loop.h"
#include "base/task.h"
#include "mozilla/Hal.h"
#include "nsAppShell.h"
@ -65,34 +63,6 @@ nsAppShell *nsAppShell::gAppShell = nsnull;
NS_IMPL_ISUPPORTS_INHERITED1(nsAppShell, nsBaseAppShell, nsIObserver)
class ScreenshotRunnable : public nsRunnable {
public:
ScreenshotRunnable(nsIAndroidBrowserApp* aBrowserApp, int aTabId, nsTArray<nsIntPoint>& aPoints, int aToken, RefCountedJavaObject* aBuffer):
mBrowserApp(aBrowserApp), mTabId(aTabId), mPoints(aPoints), mToken(aToken), mBuffer(aBuffer) {}
virtual nsresult Run() {
nsCOMPtr<nsIDOMWindow> domWindow;
nsCOMPtr<nsIBrowserTab> tab;
mBrowserApp->GetBrowserTab(mTabId, getter_AddRefs(tab));
if (!tab)
return NS_OK;
tab->GetWindow(getter_AddRefs(domWindow));
if (!domWindow)
return NS_OK;
NS_ASSERTION(mPoints.Length() == 5, "Screenshot event does not have enough coordinates");
AndroidBridge::Bridge()->TakeScreenshot(domWindow, mPoints[0].x, mPoints[0].y, mPoints[1].x, mPoints[1].y, mPoints[2].x, mPoints[2].y, mPoints[3].x, mPoints[3].y, mPoints[4].x, mPoints[4].y, mTabId, mToken, mBuffer->GetObject());
return NS_OK;
}
private:
nsCOMPtr<nsIAndroidBrowserApp> mBrowserApp;
nsTArray<nsIntPoint> mPoints;
int mTabId, mToken;
nsRefPtr<RefCountedJavaObject> mBuffer;
};
class AfterPaintListener : public nsIDOMEventListener {
public:
NS_DECL_ISUPPORTS
@ -119,15 +89,23 @@ class AfterPaintListener : public nsIDOMEventListener {
if (!paintEvent)
return NS_OK;
nsCOMPtr<nsIDOMClientRect> rect;
paintEvent->GetBoundingClientRect(getter_AddRefs(rect));
float top, left, bottom, right;
rect->GetTop(&top);
rect->GetLeft(&left);
rect->GetRight(&right);
rect->GetBottom(&bottom);
__android_log_print(ANDROID_LOG_INFO, "GeckoScreenshot", "rect: %f, %f, %f, %f", top, left, right, bottom);
AndroidBridge::NotifyPaintedRect(top, left, bottom, right);
nsCOMPtr<nsIDOMClientRectList> rects;
paintEvent->GetClientRects(getter_AddRefs(rects));
if (!rects)
return NS_OK;
PRUint32 length;
rects->GetLength(&length);
for (PRUint32 i = 0; i < length; ++i) {
float top, left, bottom, right;
nsCOMPtr<nsIDOMClientRect> rect = rects->GetItemAt(i);
if (!rect)
continue;
rect->GetTop(&top);
rect->GetLeft(&left);
rect->GetRight(&right);
rect->GetBottom(&bottom);
AndroidBridge::NotifyPaintedRect(top, left, bottom, right);
}
return NS_OK;
}
@ -447,13 +425,21 @@ nsAppShell::ProcessNextNativeEvent(bool mayWait)
break;
PRInt32 token = curEvent->Flags();
PRInt32 tabId = curEvent->MetaState();
nsCOMPtr<nsIDOMWindow> domWindow;
nsCOMPtr<nsIBrowserTab> tab;
mBrowserApp->GetBrowserTab(curEvent->MetaState(), getter_AddRefs(tab));
if (!tab)
break;
tab->GetWindow(getter_AddRefs(domWindow));
if (!domWindow)
break;
float scale = 1.0;
nsTArray<nsIntPoint> points = curEvent->Points();
RefCountedJavaObject* buffer = curEvent->ByteBuffer();
nsCOMPtr<ScreenshotRunnable> sr =
new ScreenshotRunnable(mBrowserApp, tabId, points, token, buffer);
MessageLoop::current()->PostIdleTask(
FROM_HERE, NewRunnableMethod(sr.get(), &ScreenshotRunnable::Run));
NS_ASSERTION(points.Length() == 4, "Screenshot event does not have enough coordinates");
bridge->TakeScreenshot(domWindow, points[0].x, points[0].y, points[1].x, points[1].y, points[3].x, points[3].y, curEvent->MetaState(), scale, curEvent->Flags());
break;
}