Backed out changeset 1d8e31bd28db (bug 1577192) for geckoview failure org.mozilla.geckoview.test.ScreenshotTest... On a CLOSED TREE

This commit is contained in:
Daniel Varga 2019-10-30 19:35:44 +02:00
Родитель 617d42c7ed
Коммит e4a9bb6a6b
13 изменённых файлов: 49 добавлений и 454 удалений

Просмотреть файл

@ -347,7 +347,6 @@ package org.mozilla.geckoview {
ctor protected GeckoDisplay(GeckoSession);
method @UiThread @NonNull public GeckoResult<Bitmap> capturePixels();
method @UiThread public void screenOriginChanged(int, int);
method @UiThread @NonNull public GeckoDisplay.ScreenshotBuilder screenshot();
method @UiThread public void setVerticalClipping(int);
method @UiThread public boolean shouldPinOnScreen();
method @UiThread public void surfaceChanged(@NonNull Surface, int, int);
@ -355,16 +354,6 @@ package org.mozilla.geckoview {
method @UiThread public void surfaceDestroyed();
}
public static final class GeckoDisplay.ScreenshotBuilder {
method @AnyThread @NonNull public GeckoDisplay.ScreenshotBuilder aspectPreservingSize(int);
method @AnyThread @NonNull public GeckoDisplay.ScreenshotBuilder bitmap(@Nullable Bitmap);
method @UiThread @NonNull public GeckoResult<Bitmap> capture();
method @AnyThread @NonNull public GeckoDisplay.ScreenshotBuilder scale(float);
method @AnyThread @NonNull public GeckoDisplay.ScreenshotBuilder size(int, int);
method @AnyThread @NonNull public GeckoDisplay.ScreenshotBuilder source(int, int, int, int);
method @AnyThread @NonNull public GeckoDisplay.ScreenshotBuilder source(@NonNull Rect);
}
public interface GeckoResponse<T> {
method @AnyThread public void respond(@Nullable T);
}

Просмотреть файл

@ -1,5 +1,6 @@
<html>
<head><title>Colours</title></head>
<body style="overflow:hidden; height:100%; width:100%; margin: 0px; padding: 0px; background: linear-gradient(135deg, red, white);">
<body style="background-color:green;">
<div id="fullscreen" style="width:100%;height:100%;position:fixed;top:0;left:0;z-index:100;"></div>
</body>
</html>

Просмотреть файл

@ -10,21 +10,18 @@ import android.support.test.filters.MediumTest
import android.support.test.runner.AndroidJUnit4
import android.view.Surface
import org.hamcrest.Matchers.*
import org.junit.Ignore
import org.junit.Assert.fail
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.runner.RunWith
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay
import kotlin.math.absoluteValue
import kotlin.math.max
import android.graphics.BitmapFactory
import android.graphics.Bitmap
import android.support.test.InstrumentationRegistry
import java.nio.ByteBuffer
private const val SCREEN_HEIGHT = 800
private const val SCREEN_WIDTH = 800
private const val SCREEN_HEIGHT = 100
private const val SCREEN_WIDTH = 100
@RunWith(AndroidJUnit4::class)
@MediumTest
@ -37,35 +34,11 @@ class ScreenshotTest : BaseSessionTest() {
val screenshotFile = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(screenshotFile)
val paint = Paint()
paint.shader = LinearGradient(0f, 0f, width.toFloat(), height.toFloat(), Color.RED, Color.WHITE, Shader.TileMode.MIRROR)
paint.color = Color.rgb(0, 128, 0)
canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
return screenshotFile
}
companion object {
/**
* Compares two Bitmaps and returns the largest color element difference (red, green or blue)
*/
public fun imageElementDifference(b1: Bitmap, b2: Bitmap): Int {
return if (b1.width == b2.width && b1.height == b2.height) {
val pixels1 = IntArray(b1.width * b1.height)
val pixels2 = IntArray(b2.width * b2.height)
b1.getPixels(pixels1, 0, b1.width, 0, 0, b1.width, b1.height)
b2.getPixels(pixels2, 0, b2.width, 0, 0, b2.width, b2.height)
var maxDiff = 0
for (i in 0 until pixels1.size) {
val redDiff = (Color.red(pixels1[i]) - Color.red(pixels2[i])).absoluteValue
val greenDiff = (Color.green(pixels1[i]) - Color.green(pixels2[i])).absoluteValue
val blueDiff = (Color.blue(pixels1[i]) - Color.blue(pixels2[i])).absoluteValue
maxDiff = max(maxDiff, max(redDiff, max(greenDiff, blueDiff)))
}
maxDiff
} else {
256
}
}
}
private fun assertScreenshotResult(result: GeckoResult<Bitmap>, comparisonImage: Bitmap) {
sessionRule.waitForResult(result).let {
assertThat("Screenshot is not null",
@ -74,8 +47,11 @@ class ScreenshotTest : BaseSessionTest() {
assertThat("Heights are the same", comparisonImage.height, equalTo(it.height))
assertThat("Byte counts are the same", comparisonImage.byteCount, equalTo(it.byteCount))
assertThat("Configs are the same", comparisonImage.config, equalTo(it.config))
assertThat("Images are almost identical",
imageElementDifference(comparisonImage, it), lessThanOrEqualTo(1))
val comparisonPixels: ByteBuffer = ByteBuffer.allocate(comparisonImage.byteCount)
comparisonImage.copyPixelsToBuffer(comparisonPixels)
val itPixels: ByteBuffer = ByteBuffer.allocate(it.byteCount)
it.copyPixelsToBuffer(itPixels)
assertThat("Bytes are the same", comparisonPixels, equalTo(itPixels))
}
}
@ -123,143 +99,4 @@ class ScreenshotTest : BaseSessionTest() {
sessionRule.waitForResult(result)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenshotToBitmap() {
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH, SCREEN_HEIGHT)
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(it.screenshot().capture(), screenshotFile)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenshotScaledToSize() {
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(it.screenshot().size(SCREEN_WIDTH/2, SCREEN_HEIGHT/2).capture(), screenshotFile)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenShotScaledWithScale() {
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(it.screenshot().scale(0.5f).capture(), screenshotFile)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenShotScaledWithAspectPreservingSize() {
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(it.screenshot().aspectPreservingSize(SCREEN_WIDTH/2).capture(), screenshotFile)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun recycleBitmap() {
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH, SCREEN_HEIGHT)
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
val call1 = it.screenshot().capture()
assertScreenshotResult(call1, screenshotFile)
val call2 = it.screenshot().bitmap(call1.poll(1000)).capture()
assertScreenshotResult(call2, screenshotFile)
val call3 = it.screenshot().bitmap(call2.poll(1000)).capture()
assertScreenshotResult(call3, screenshotFile)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenshotWholeRegion() {
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH, SCREEN_HEIGHT)
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(it.screenshot().source(0,0,SCREEN_WIDTH, SCREEN_HEIGHT).capture(), screenshotFile)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenshotWholeRegionScaled() {
val screenshotFile = getComparisonScreenshot(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(it.screenshot()
.source(0,0,SCREEN_WIDTH, SCREEN_HEIGHT)
.size(SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
.capture(), screenshotFile)
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenshotQuarters() {
val res = InstrumentationRegistry.getTargetContext().resources
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(
it.screenshot()
.source(0,0,SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
.capture(), BitmapFactory.decodeResource(res, R.drawable.colors_tl))
assertScreenshotResult(
it.screenshot()
.source(SCREEN_WIDTH/2,SCREEN_HEIGHT/2,SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
.capture(), BitmapFactory.decodeResource(res, R.drawable.colors_br))
}
}
@WithDisplay(height = SCREEN_HEIGHT, width = SCREEN_WIDTH)
@Test
fun screenshotQuartersScaled() {
val res = InstrumentationRegistry.getTargetContext().resources
sessionRule.session.loadTestPath(COLORS_HTML_PATH)
sessionRule.waitForPageStop()
sessionRule.display?.let {
assertScreenshotResult(
it.screenshot()
.source(0,0,SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
.size(SCREEN_WIDTH/4, SCREEN_WIDTH/4)
.capture(), BitmapFactory.decodeResource(res, R.drawable.colors_tl_scaled))
assertScreenshotResult(
it.screenshot()
.source(SCREEN_WIDTH/2,SCREEN_HEIGHT/2,SCREEN_WIDTH/2, SCREEN_HEIGHT/2)
.size(SCREEN_WIDTH/4, SCREEN_WIDTH/4)
.capture(), BitmapFactory.decodeResource(res, R.drawable.colors_br_scaled))
}
}
}

Просмотреть файл

@ -13,11 +13,8 @@ import org.junit.runner.RunWith
import org.mozilla.geckoview.GeckoResult
import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay
import android.graphics.Bitmap
import org.hamcrest.Matchers
import org.hamcrest.Matchers.equalTo
import java.nio.ByteBuffer
import kotlin.math.absoluteValue
import kotlin.math.max
private const val SCREEN_HEIGHT = 100
@ -52,10 +49,11 @@ class VerticalClippingTest : BaseSessionTest() {
assertThat("Heights are the same", comparisonImage.height, equalTo(it.height))
assertThat("Byte counts are the same", comparisonImage.byteCount, equalTo(it.byteCount))
assertThat("Configs are the same", comparisonImage.config, equalTo(it.config))
assertThat("Images are almost identical",
ScreenshotTest.Companion.imageElementDifference(comparisonImage, it),
Matchers.lessThanOrEqualTo(1))
}
val comparisonPixels: ByteBuffer = ByteBuffer.allocate(comparisonImage.byteCount)
comparisonImage.copyPixelsToBuffer(comparisonPixels)
val itPixels: ByteBuffer = ByteBuffer.allocate(it.byteCount)
it.copyPixelsToBuffer(itPixels)
assertThat("Bytes are the same", comparisonPixels, equalTo(itPixels)) }
}

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 5.5 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.8 KiB

Просмотреть файл

@ -7,17 +7,12 @@
package org.mozilla.geckoview;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
import android.view.Surface;
import org.mozilla.gecko.util.ThreadUtils;
import java.nio.ByteBuffer;
/**
* Applications use a GeckoDisplay instance to provide {@link GeckoSession} with a {@link Surface} for
* displaying content. To ensure drawing only happens on a valid {@link Surface}, {@link GeckoSession}
@ -70,6 +65,7 @@ public class GeckoDisplay {
if ((left < 0) || (top < 0)) {
throw new IllegalArgumentException("Parameters can not be negative.");
}
if (mSession.getDisplay() == this) {
mSession.onSurfaceChanged(surface, left, top, width, height);
}
@ -160,203 +156,13 @@ public class GeckoDisplay {
*/
@UiThread
public @NonNull GeckoResult<Bitmap> capturePixels() {
return screenshot().capture();
}
/**
* Builder to construct screenshot requests.
*/
final static public class ScreenshotBuilder {
private static final int NONE = 0;
private static final int SCALE = 1;
private static final int ASPECT = 2;
private static final int FULL = 3;
private static final int RECYCLE = 4;
private final GeckoSession mSession;
private int mOffsetX;
private int mOffsetY;
private int mSrcWidth;
private int mSrcHeight;
private int mOutWidth;
private int mOutHeight;
private int mAspectPreservingWidth;
private float mScale;
private Bitmap mRecycle;
private int mSizeType;
/* package */ ScreenshotBuilder(final GeckoSession session) {
this.mSizeType = NONE;
this.mSession = session;
ThreadUtils.assertOnUiThread();
if (!mSession.isCompositorReady()) {
return GeckoResult.fromException(
new IllegalStateException("Compositor must be ready before pixels can be captured"));
}
/**
* The screenshot will be of a region instead of the entire screen
* @param x Left most pixel of the source region.
* @param y Top most pixel of the source region.
* @param width Width of the source region in screen pixels
* @param height Height of the source region in screen pixels
* @return The builder
*/
@AnyThread
public @NonNull ScreenshotBuilder source(final int x, final int y, final int width, final int height) {
mOffsetX = x;
mOffsetY = y;
mSrcWidth = width;
mSrcHeight = height;
return this;
}
/**
* The screenshot will be of a region instead of the entire screen
* @param source Region of the screen to capture in screen pixels
* @return The builder
*/
@AnyThread
public @NonNull ScreenshotBuilder source(final @NonNull Rect source) {
mOffsetX = source.left;
mOffsetY = source.top;
mSrcWidth = source.width();
mSrcHeight = source.height();
return this;
}
private void checkAndSetSizeType(final int sizeType) {
if (mSizeType != NONE) {
throw new IllegalStateException("Size has already been set.");
}
mSizeType = sizeType;
}
/**
* The width of the bitmap to create when taking the screenshot. The height will be
* calculated to match the aspect ratio of the source as closely as possible. The source
* screenshot will be scaled into the resulting Bitmap.
* @param width of the result Bitmap in screen pixels.
* @return The builder
* @throws IllegalStateException if the size has already been set in some other way.
*/
@AnyThread
public @NonNull ScreenshotBuilder aspectPreservingSize(final int width) {
checkAndSetSizeType(ASPECT);
mAspectPreservingWidth = width;
return this;
}
/**
* The scale of the bitmap relative to the source. The height and width of the output
* bitmap will be within one pixel of this multiple of the source dimensions. The source
* screenshot will be scaled into the resulting Bitmap.
* @param scale of the result Bitmap relative to the source.
* @return The builder
* @throws IllegalStateException if the size has already been set in some other way.
*/
@AnyThread
public @NonNull ScreenshotBuilder scale(final float scale) {
checkAndSetSizeType(SCALE);
mScale = scale;
return this;
}
/**
* Size of the bitmap to create when taking the screenshot. The source screenshot will be
* scaled into the resulting Bitmap
* @param width of the result Bitmap in screen pixels.
* @param height of the result Bitmap in screen pixels.
* @return The builder
* @throws IllegalStateException if the size has already been set in some other way.
*/
@AnyThread
public @NonNull ScreenshotBuilder size(final int width, final int height) {
checkAndSetSizeType(FULL);
mOutWidth = width;
mOutHeight = height;
return this;
}
/**
* Instead of creating a new Bitmap for the result, the builder will use the passed Bitmap.
* @param bitmap The Bitmap to use in the result.
* @return The builder.
* @throws IllegalStateException if the size has already been set in some other way.
*/
@AnyThread
public @NonNull ScreenshotBuilder bitmap(final @Nullable Bitmap bitmap) {
checkAndSetSizeType(RECYCLE);
mRecycle = bitmap;
return this;
}
/**
* Request a {@link Bitmap} of the requested portion of the web page currently being
* rendered using any parameters specified with the builder.
*
* This function must be called on the UI thread.
*
* @return A {@link GeckoResult} that completes with a {@link Bitmap} containing
* the pixels and size information of the requested portion of the visible web page.
*/
@UiThread
public @NonNull GeckoResult<Bitmap> capture() {
ThreadUtils.assertOnUiThread();
if (!mSession.isCompositorReady()) {
throw new IllegalStateException("Compositor must be ready before pixels can be captured");
}
final GeckoResult<ByteBuffer> result = new GeckoResult<>();
final Bitmap target;
final Rect rect = new Rect();
if (mSrcWidth == 0 || mSrcHeight == 0) {
// Source is unset or invalid, use defaults.
mSession.getSurfaceBounds(rect);
mSrcWidth = rect.width();
mSrcHeight = rect.height();
}
switch (mSizeType) {
case NONE:
mOutWidth = mSrcWidth;
mOutHeight = mSrcHeight;
break;
case SCALE:
mSession.getSurfaceBounds(rect);
mOutWidth = (int) (rect.width() * mScale);
mOutHeight = (int) (rect.height() * mScale);
break;
case ASPECT:
mSession.getSurfaceBounds(rect);
mOutWidth = mAspectPreservingWidth;
mOutHeight = (int) (rect.height() * (mAspectPreservingWidth / (double) rect.width()));
break;
case RECYCLE:
mOutWidth = mRecycle.getWidth();
mOutHeight = mRecycle.getHeight();
break;
// case FULL does not need to be handled, as width and height are already set.
}
if (mRecycle == null) {
target = Bitmap.createBitmap(mOutWidth, mOutHeight, Bitmap.Config.ARGB_8888);
} else {
target = mRecycle;
}
mSession.mCompositor.requestScreenPixels(result, mOffsetX, mOffsetY, mSrcWidth, mSrcHeight, mOutWidth, mOutHeight);
return result.then( buffer -> {
target.copyPixelsFromBuffer(buffer);
return GeckoResult.fromValue(target);
});
}
}
/**
* Creates a new screenshot builder.
* @return The new {@link ScreenshotBuilder}
*/
@UiThread
public @NonNull ScreenshotBuilder screenshot() {
return new ScreenshotBuilder(mSession);
GeckoResult<Bitmap> result = new GeckoResult<>();
mSession.mCompositor.requestScreenPixels(result);
return result;
}
}

Просмотреть файл

@ -9,7 +9,6 @@ package org.mozilla.geckoview;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.AbstractSequentialList;
import java.util.ArrayList;
import java.util.HashMap;
@ -37,6 +36,7 @@ import org.mozilla.gecko.util.ThreadUtils;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
@ -234,10 +234,7 @@ public class GeckoSession implements Parcelable {
public native void setDefaultClearColor(int color);
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
/* package */ native void requestScreenPixels(final GeckoResult<ByteBuffer> result,
final int x, final int y,
final int srcWidth, final int srcHeight,
final int outWidth, final int outHeight);
/* package */ native void requestScreenPixels(final GeckoResult<Bitmap> result);
@WrapForJNI(calledFrom = "ui", dispatchTo = "current")
public native void enableLayerUpdateNotifications(boolean enable);

Просмотреть файл

@ -56,8 +56,6 @@ exclude: true
to the session it holds.
- Changed [`AutofillElement.children`][71.20] interface to `Collection` to provide
an efficient way to pre-allocate memory when filling `ViewStructure`.
- Added [`GeckoDisplay.screenshot`][71.22] allowing apps finer grain control over screenshots.
([bug 1577192]({{bugzilla}}1577192))
[71.1]: {{javadoc_uri}}/RuntimeTelemetry.Delegate.html#onBooleanScalar-org.mozilla.geckoview.RuntimeTelemetry.Metric-
[71.2]: {{javadoc_uri}}/RuntimeTelemetry.Delegate.html#onLongScalar-org.mozilla.geckoview.RuntimeTelemetry.Metric-
@ -79,7 +77,6 @@ exclude: true
[71.19]: {{javadoc_uri}}/GeckoSession.html#getAutofillElements--
[71.20]: {{javadoc_uri}}/AutofillElement.html
[71.21]: {{javadoc_uri}}/GeckoView.html#setAutofillEnabled-boolean-
[71.22]: {{javadoc_uri}}/GeckoDisplay.html#screenshot--
## v70
- Added API for session context assignment
@ -402,4 +399,4 @@ exclude: true
[65.24]: {{javadoc_uri}}/CrashReporter.html#sendCrashReport-android.content.Context-android.os.Bundle-java.lang.String-
[65.25]: {{javadoc_uri}}/GeckoResult.html
[api-version]: ccbb8bca379f33fa67a332dcf8dea131249ce2ca
[api-version]: ee3ceb65db78c3a801f525465ff3c6e9eca22ae9

Просмотреть файл

@ -98,8 +98,6 @@ using mozilla::dom::ContentParent;
#include "nsPrintfCString.h"
#include "nsString.h"
#include "JavaBuiltins.h"
#include "mozilla/ipc/Shmem.h"
using namespace mozilla;
@ -800,22 +798,7 @@ class nsWindow::LayerViewSupport final
GeckoSession::Compositor::WeakRef mCompositor;
Atomic<bool, ReleaseAcquire> mCompositorPaused;
jni::Object::GlobalRef mSurface;
struct CaptureRequest {
explicit CaptureRequest() : mResult(nullptr) {}
explicit CaptureRequest(java::GeckoResult::GlobalRef aResult,
const ScreenRect& aSource,
const IntSize& aOutputSize)
: mResult(aResult), mSource(aSource), mOutputSize(aOutputSize) {}
// where to send the pixels
java::GeckoResult::GlobalRef mResult;
ScreenRect mSource;
IntSize mOutputSize;
};
std::queue<CaptureRequest> mCapturePixelsResults;
std::queue<java::GeckoResult::GlobalRef> mCapturePixelsResults;
// In order to use Event::HasSameTypeAs in PostTo(), we cannot make
// LayerViewEvent a template because each template instantiation is
@ -881,8 +864,7 @@ class nsWindow::LayerViewSupport final
results = &mCapturePixelsResults, window = &mWindow] {
if (LockedWindowPtr lock{*window}) {
while (!results->empty()) {
auto aResult =
java::GeckoResult::LocalRef(results->front().mResult);
auto aResult = java::GeckoResult::LocalRef(results->front());
if (aResult) {
aResult->CompleteExceptionally(
java::sdk::IllegalStateException::New(
@ -916,24 +898,19 @@ class nsWindow::LayerViewSupport final
return child.forget();
}
int8_t* FlipScreenPixels(Shmem& aMem, const ScreenIntSize& aInSize,
const ScreenRect& aInRegion,
const IntSize& aOutSize) {
int8_t* FlipScreenPixels(Shmem& aMem, const ScreenIntSize& aSize) {
const IntSize size(aSize.width, aSize.height);
RefPtr<DataSourceSurface> image = gfx::CreateDataSourceSurfaceFromData(
IntSize(aInSize.width, aInSize.height), SurfaceFormat::B8G8R8A8,
aMem.get<uint8_t>(),
StrideForFormatAndWidth(SurfaceFormat::B8G8R8A8, aInSize.width));
size, SurfaceFormat::B8G8R8A8, aMem.get<uint8_t>(),
StrideForFormatAndWidth(SurfaceFormat::B8G8R8A8, aSize.width));
RefPtr<DrawTarget> drawTarget =
gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
aOutSize, SurfaceFormat::B8G8R8A8);
size, SurfaceFormat::B8G8R8A8);
drawTarget->SetTransform(Matrix::Scaling(1.0, -1.0) *
Matrix::Translation(0, aOutSize.height));
Matrix::Translation(0, aSize.height));
gfx::Rect srcRect(aInRegion.x,
(aInSize.height - aInRegion.height) - aInRegion.y,
aInRegion.width, aInRegion.height);
gfx::Rect destRect(0, 0, aOutSize.width, aOutSize.height);
drawTarget->DrawSurface(image, destRect, srcRect);
gfx::Rect drawRect(0, 0, aSize.width, aSize.height);
drawTarget->DrawSurface(image, drawRect, drawRect);
RefPtr<SourceSurface> snapshot = drawTarget->Snapshot();
RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
@ -1147,18 +1124,13 @@ class nsWindow::LayerViewSupport final
}
}
void RequestScreenPixels(jni::Object::Param aResult, int32_t aXOffset,
int32_t aYOffset, int32_t aSrcWidth,
int32_t aSrcHeight, int32_t aOutWidth,
int32_t aOutHeight) {
void RequestScreenPixels(jni::Object::Param aResult) {
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
int size = 0;
if (LockedWindowPtr window{mWindow}) {
mCapturePixelsResults.push(CaptureRequest(
java::GeckoResult::GlobalRef(java::GeckoResult::LocalRef(aResult)),
ScreenRect(aXOffset, aYOffset, aSrcWidth, aSrcHeight),
IntSize(aOutWidth, aOutHeight)));
mCapturePixelsResults.push(
java::GeckoResult::GlobalRef(java::GeckoResult::LocalRef(aResult)));
size = mCapturePixelsResults.size();
}
@ -1172,22 +1144,20 @@ class nsWindow::LayerViewSupport final
void RecvScreenPixels(Shmem&& aMem, const ScreenIntSize& aSize) {
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
CaptureRequest aCaptureRequest;
java::GeckoResult::LocalRef aResult = nullptr;
if (LockedWindowPtr window{mWindow}) {
aCaptureRequest = mCapturePixelsResults.front();
aResult = java::GeckoResult::LocalRef(aCaptureRequest.mResult);
aResult = java::GeckoResult::LocalRef(mCapturePixelsResults.front());
if (aResult) {
mCapturePixelsResults.pop();
}
}
if (aResult) {
auto pixels = mozilla::jni::ByteBuffer::New(
FlipScreenPixels(aMem, aSize, aCaptureRequest.mSource,
aCaptureRequest.mOutputSize),
aMem.Size<int8_t>());
aResult->Complete(pixels);
auto pixels = mozilla::jni::ByteBuffer::New(FlipScreenPixels(aMem, aSize),
aMem.Size<int8_t>());
auto bitmap = java::sdk::Bitmap::CreateBitmap(
aSize.width, aSize.height, java::sdk::Config::ARGB_8888());
bitmap->CopyPixelsFromBuffer(pixels);
aResult->Complete(bitmap);
}
// Pixels have been copied, so Dealloc Shmem