Commit 8800027a authored by Brad Lassey's avatar Brad Lassey
Browse files

backout bug 755070

parent 186e0789
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@ import android.hardware.*;
import android.location.*;
import android.util.FloatMath;
import android.util.DisplayMetrics;
import java.nio.ByteBuffer;

import android.util.Log;

@@ -101,8 +100,6 @@ public class GeckoEvent {

    public int mNativeWindow;

    public ByteBuffer mBuffer;

    public GeckoEvent() {
        mType = NATIVE_POKE;
    }
+0 −8
Original line number Diff line number Diff line
@@ -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,
+0 −4
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -697,7 +697,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));
        }
    }
    
+56 −137
Original line number Diff line number Diff line
@@ -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 LinkedList<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);
        }
        }

        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
@@ -2206,8 +2211,6 @@ class ScreenshotHandler {
        float sy = viewport.cssPageRectTop;
        float sw = viewport.cssPageRectRight - viewport.cssPageRectLeft;
        float sh = viewport.cssPageRectBottom - viewport.cssPageRectTop;
        if (sw == 0 || sh == 0)
            return;
        int maxPixels = Math.min(ScreenshotLayer.getMaxNumPixels(), sMaxTextureSize * sMaxTextureSize);
        // 2Mb of 16bit image data
        // may be bumped by up to 4x for power of 2 alignment
@@ -2221,98 +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);
        if (numSlices == 0)
            return;
        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));
    }
}
Loading