Commit a3b83ee5 authored by ckitagawa's avatar ckitagawa Committed by Chromium LUCI CQ

[Paint Preview] Support alt compositing mode for Long Screenshots

This addresses two shortcomings of PlayerCompositorDelegate for the
Long Screenshots use case:
1. An in-memory PaintPreviewProto is provided from Java rather than one
   from disk.
2. Compositing should occur to a single SkPicture using the MainFrame
   mode of the compositor rather than the SeparateFrame mode.

This CL also makes the MainFrame mode return the dimensions of the
SkPicture so that Long Screenshot can leverage this information.

Change-Id: If0b2d666f7459b94f4501c23808c504826a0112a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2578076Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Reviewed-by: default avatarMehran Mahmoudi <mahmoudi@chromium.org>
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#835290}
parent f41cfc25
...@@ -37,6 +37,7 @@ android_library("java") { ...@@ -37,6 +37,7 @@ android_library("java") {
"//chrome/browser/ui/messages/android:java", "//chrome/browser/ui/messages/android:java",
"//components/browser_ui/styles/android:java", "//components/browser_ui/styles/android:java",
"//components/paint_preview/browser/android:java", "//components/paint_preview/browser/android:java",
"//components/paint_preview/common/proto:proto_java",
"//components/paint_preview/player/android:java", "//components/paint_preview/player/android:java",
"//content/public/android:content_java", "//content/public/android:content_java",
"//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_annotation_annotation_java",
...@@ -72,6 +73,7 @@ android_library("javatests") { ...@@ -72,6 +73,7 @@ android_library("javatests") {
"//chrome/browser/ui/messages/android:java", "//chrome/browser/ui/messages/android:java",
"//chrome/test/android:chrome_java_test_support", "//chrome/test/android:chrome_java_test_support",
"//components/paint_preview/browser/android:java", "//components/paint_preview/browser/android:java",
"//components/paint_preview/common/proto:proto_java",
"//components/paint_preview/player/android:java", "//components/paint_preview/player/android:java",
"//content/public/android:content_java", "//content/public/android:content_java",
"//content/public/test/android:content_java_test_support", "//content/public/test/android:content_java_test_support",
......
...@@ -60,7 +60,7 @@ public class DemoPaintPreviewTest { ...@@ -60,7 +60,7 @@ public class DemoPaintPreviewTest {
sMockService = Mockito.mock(PaintPreviewTabService.class); sMockService = Mockito.mock(PaintPreviewTabService.class);
TabbedPaintPreview.overridePaintPreviewTabServiceForTesting(sMockService); TabbedPaintPreview.overridePaintPreviewTabServiceForTesting(sMockService);
PlayerManager.overrideCompositorDelegateFactoryForTesting( PlayerManager.overrideCompositorDelegateFactoryForTesting(
TabbedPaintPreviewTest.TestCompositorDelegate::new); new TabbedPaintPreviewTest.TestCompositorDelegateFactory());
} }
@AfterClass @AfterClass
......
...@@ -59,7 +59,7 @@ public class StartupPaintPreviewTest { ...@@ -59,7 +59,7 @@ public class StartupPaintPreviewTest {
Mockito.doReturn(true).when(mockService).hasCaptureForTab(Mockito.anyInt()); Mockito.doReturn(true).when(mockService).hasCaptureForTab(Mockito.anyInt());
TabbedPaintPreview.overridePaintPreviewTabServiceForTesting(mockService); TabbedPaintPreview.overridePaintPreviewTabServiceForTesting(mockService);
PlayerManager.overrideCompositorDelegateFactoryForTesting( PlayerManager.overrideCompositorDelegateFactoryForTesting(
TabbedPaintPreviewTest.TestCompositorDelegate::new); new TabbedPaintPreviewTest.TestCompositorDelegateFactory());
} }
@AfterClass @AfterClass
......
...@@ -10,6 +10,7 @@ import android.os.Handler; ...@@ -10,6 +10,7 @@ import android.os.Handler;
import android.os.Parcel; import android.os.Parcel;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.test.filters.MediumTest; import androidx.test.filters.MediumTest;
import org.junit.After; import org.junit.After;
...@@ -32,6 +33,7 @@ import org.chromium.chrome.browser.paint_preview.services.PaintPreviewTabService ...@@ -32,6 +33,7 @@ import org.chromium.chrome.browser.paint_preview.services.PaintPreviewTabService
import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.components.paint_preview.common.proto.PaintPreview.PaintPreviewProto;
import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider; import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider;
import org.chromium.components.paintpreview.player.PlayerCompositorDelegate; import org.chromium.components.paintpreview.player.PlayerCompositorDelegate;
import org.chromium.components.paintpreview.player.PlayerManager; import org.chromium.components.paintpreview.player.PlayerManager;
...@@ -53,12 +55,37 @@ public class TabbedPaintPreviewTest { ...@@ -53,12 +55,37 @@ public class TabbedPaintPreviewTest {
private static final String TEST_URL = "/chrome/test/data/android/about.html"; private static final String TEST_URL = "/chrome/test/data/android/about.html";
/**
* Implementation of {@link PlayerCompositorDelegate.Factory} for tests.
*/
public static class TestCompositorDelegateFactory implements PlayerCompositorDelegate.Factory {
@Override
public PlayerCompositorDelegate create(NativePaintPreviewServiceProvider service, GURL url,
String directoryKey, boolean mainFrameMode,
@NonNull PlayerCompositorDelegate.CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback) {
return new TestCompositorDelegate(service, null, url, directoryKey, mainFrameMode,
compositorListener, compositorErrorCallback);
}
@Override
public PlayerCompositorDelegate createForProto(NativePaintPreviewServiceProvider service,
@Nullable PaintPreviewProto proto, GURL url, String directoryKey,
boolean mainFrameMode,
@NonNull PlayerCompositorDelegate.CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback) {
Assert.fail("createForProto shouldn't be called");
return null;
}
}
@Before @Before
public void setUp() { public void setUp() {
PaintPreviewTabService mockService = Mockito.mock(PaintPreviewTabService.class); PaintPreviewTabService mockService = Mockito.mock(PaintPreviewTabService.class);
Mockito.doReturn(true).when(mockService).hasCaptureForTab(Mockito.anyInt()); Mockito.doReturn(true).when(mockService).hasCaptureForTab(Mockito.anyInt());
TabbedPaintPreview.overridePaintPreviewTabServiceForTesting(mockService); TabbedPaintPreview.overridePaintPreviewTabServiceForTesting(mockService);
PlayerManager.overrideCompositorDelegateFactoryForTesting(TestCompositorDelegate::new); PlayerManager.overrideCompositorDelegateFactoryForTesting(
new TestCompositorDelegateFactory());
mActivityTestRule.startMainActivityWithURL( mActivityTestRule.startMainActivityWithURL(
mActivityTestRule.getTestServer().getURL(TEST_URL)); mActivityTestRule.getTestServer().getURL(TEST_URL));
} }
...@@ -296,9 +323,12 @@ public class TabbedPaintPreviewTest { ...@@ -296,9 +323,12 @@ public class TabbedPaintPreviewTest {
public static class TestCompositorDelegate implements PlayerCompositorDelegate { public static class TestCompositorDelegate implements PlayerCompositorDelegate {
private int mNextRequestId; private int mNextRequestId;
TestCompositorDelegate(NativePaintPreviewServiceProvider service, GURL url, TestCompositorDelegate(NativePaintPreviewServiceProvider service,
String directoryKey, @NonNull CompositorListener compositorListener, @Nullable PaintPreviewProto proto, GURL url, String directoryKey,
boolean mainFrameMode, @NonNull CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback) { Callback<Integer> compositorErrorCallback) {
Assert.assertNull(proto);
Assert.assertFalse(mainFrameMode);
new Handler().postDelayed(() -> { new Handler().postDelayed(() -> {
Parcel parcel = Parcel.obtain(); Parcel parcel = Parcel.obtain();
parcel.writeLong(4577L); parcel.writeLong(4577L);
...@@ -326,6 +356,14 @@ public class TabbedPaintPreviewTest { ...@@ -326,6 +356,14 @@ public class TabbedPaintPreviewTest {
return requestId; return requestId;
} }
@Override
public int requestBitmap(Rect clipRect, float scaleFactor, Callback<Bitmap> bitmapCallback,
Runnable errorCallback) {
Assert.fail("The GUIDless version of TestCompositorDelegate#requestBitmap() shouldn't"
+ " be called.");
return 0;
}
@Override @Override
public boolean cancelBitmapRequest(int requestId) { public boolean cancelBitmapRequest(int requestId) {
return false; return false;
......
...@@ -85,6 +85,7 @@ android_library("java") { ...@@ -85,6 +85,7 @@ android_library("java") {
"//base:base_java", "//base:base_java",
"//base:jni_java", "//base:jni_java",
"//components/paint_preview/browser/android:java", "//components/paint_preview/browser/android:java",
"//components/paint_preview/common/proto:proto_java",
"//third_party/android_deps:androidx_annotation_annotation_java", "//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_swipe_refresh:android_swipe_refresh_java", "//third_party/android_swipe_refresh:android_swipe_refresh_java",
"//ui/android:ui_java", "//ui/android:ui_java",
...@@ -129,6 +130,7 @@ android_library("javatests") { ...@@ -129,6 +130,7 @@ android_library("javatests") {
":player_java_test_support", ":player_java_test_support",
"//base:base_java", "//base:base_java",
"//base:base_java_test_support", "//base:base_java_test_support",
"//components/paint_preview/common/proto:proto_java",
"//content/public/android:content_java", "//content/public/android:content_java",
"//content/public/test/android:content_java_test_support", "//content/public/test/android:content_java_test_support",
"//third_party/android_deps:androidx_test_runner_java", "//third_party/android_deps:androidx_test_runner_java",
......
...@@ -8,9 +8,11 @@ import android.graphics.Bitmap; ...@@ -8,9 +8,11 @@ import android.graphics.Bitmap;
import android.graphics.Rect; import android.graphics.Rect;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.UnguessableToken; import org.chromium.base.UnguessableToken;
import org.chromium.components.paint_preview.common.proto.PaintPreview.PaintPreviewProto;
import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider; import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider;
import org.chromium.url.GURL; import org.chromium.url.GURL;
...@@ -22,7 +24,13 @@ public interface PlayerCompositorDelegate { ...@@ -22,7 +24,13 @@ public interface PlayerCompositorDelegate {
/** An interface that creates an instance of {@link PlayerCompositorDelegate}. */ /** An interface that creates an instance of {@link PlayerCompositorDelegate}. */
interface Factory { interface Factory {
PlayerCompositorDelegate create(NativePaintPreviewServiceProvider service, GURL url, PlayerCompositorDelegate create(NativePaintPreviewServiceProvider service, GURL url,
String directoryKey, @NonNull CompositorListener compositorListener, String directoryKey, boolean mainFrameMode,
@NonNull CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback);
PlayerCompositorDelegate createForProto(NativePaintPreviewServiceProvider service,
@Nullable PaintPreviewProto proto, GURL url, String directoryKey,
boolean mainFrameMode, @NonNull CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback); Callback<Integer> compositorErrorCallback);
} }
...@@ -72,7 +80,7 @@ public interface PlayerCompositorDelegate { ...@@ -72,7 +80,7 @@ public interface PlayerCompositorDelegate {
* Requests a new bitmap for a frame from the Paint Preview compositor. * Requests a new bitmap for a frame from the Paint Preview compositor.
* @param frameGuid The GUID of the frame. * @param frameGuid The GUID of the frame.
* @param clipRect The {@link Rect} for which the bitmap is requested. * @param clipRect The {@link Rect} for which the bitmap is requested.
* @param scaleFactor The scale factor at which the bitmap should be rendered. * @param scaleFactor The scale factor at which the bitmap should be rastered.
* @param bitmapCallback The callback that receives the bitmap once it's ready. Won't get called * @param bitmapCallback The callback that receives the bitmap once it's ready. Won't get called
* if there are any errors. * if there are any errors.
* @param errorCallback Gets notified if there are any errors. Won't get called otherwise. * @param errorCallback Gets notified if there are any errors. Won't get called otherwise.
...@@ -82,6 +90,20 @@ public interface PlayerCompositorDelegate { ...@@ -82,6 +90,20 @@ public interface PlayerCompositorDelegate {
int requestBitmap(UnguessableToken frameGuid, Rect clipRect, float scaleFactor, int requestBitmap(UnguessableToken frameGuid, Rect clipRect, float scaleFactor,
Callback<Bitmap> bitmapCallback, Runnable errorCallback); Callback<Bitmap> bitmapCallback, Runnable errorCallback);
/**
* Requests a new bitmap for a frame from the Paint Preview compositor if {@link mainFrameMode}
* was passed as true as a parameter in the {@link Factory}
* @param clipRect The {@link Rect} for which the bitmap is requested.
* @param scaleFactor The scale factor at which the bitmap should be rastered.
* @param bitmapCallback The callback that receives the bitmap once it's ready. Won't get called
* if there are any errors.
* @param errorCallback Gets notified if there are any errors. Won't get called otherwise.
* @return an int representing the ID for the bitmap request. Can be used with {@link
* cancelBitmapRequest(int)} to cancel the request if possible.
*/
int requestBitmap(Rect clipRect, float scaleFactor, Callback<Bitmap> bitmapCallback,
Runnable errorCallback);
/** /**
* Cancels the bitmap request for the provided ID. * Cancels the bitmap request for the provided ID.
* @param requestID the request to try to cancel. * @param requestID the request to try to cancel.
......
...@@ -9,6 +9,7 @@ import android.graphics.Rect; ...@@ -9,6 +9,7 @@ import android.graphics.Rect;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.SysUtils; import org.chromium.base.SysUtils;
...@@ -16,6 +17,7 @@ import org.chromium.base.UnguessableToken; ...@@ -16,6 +17,7 @@ import org.chromium.base.UnguessableToken;
import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.components.paint_preview.common.proto.PaintPreview.PaintPreviewProto;
import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider; import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider;
import org.chromium.url.GURL; import org.chromium.url.GURL;
...@@ -34,14 +36,15 @@ class PlayerCompositorDelegateImpl implements PlayerCompositorDelegate { ...@@ -34,14 +36,15 @@ class PlayerCompositorDelegateImpl implements PlayerCompositorDelegate {
private long mNativePlayerCompositorDelegate; private long mNativePlayerCompositorDelegate;
private List<Runnable> mMemoryPressureListeners = new ArrayList<>(); private List<Runnable> mMemoryPressureListeners = new ArrayList<>();
PlayerCompositorDelegateImpl(NativePaintPreviewServiceProvider service, GURL url, PlayerCompositorDelegateImpl(NativePaintPreviewServiceProvider service,
String directoryKey, @NonNull CompositorListener compositorListener, @Nullable PaintPreviewProto proto, GURL url, String directoryKey, boolean mainFrameMode,
@NonNull CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback) { Callback<Integer> compositorErrorCallback) {
mCompositorListener = compositorListener; mCompositorListener = compositorListener;
if (service != null && service.getNativeBaseService() != 0) { if (service != null && service.getNativeBaseService() != 0) {
mNativePlayerCompositorDelegate = PlayerCompositorDelegateImplJni.get().initialize(this, mNativePlayerCompositorDelegate = PlayerCompositorDelegateImplJni.get().initialize(this,
service.getNativeBaseService(), url.getSpec(), directoryKey, service.getNativeBaseService(), (proto != null) ? proto.toByteArray() : null,
compositorErrorCallback, url.getSpec(), directoryKey, mainFrameMode, compositorErrorCallback,
SysUtils.amountOfPhysicalMemoryKB() < LOW_MEMORY_THRESHOLD_KB); SysUtils.amountOfPhysicalMemoryKB() < LOW_MEMORY_THRESHOLD_KB);
} }
// TODO(crbug.com/1021590): Handle initialization errors when // TODO(crbug.com/1021590): Handle initialization errors when
...@@ -80,6 +83,12 @@ class PlayerCompositorDelegateImpl implements PlayerCompositorDelegate { ...@@ -80,6 +83,12 @@ class PlayerCompositorDelegateImpl implements PlayerCompositorDelegate {
clipRect.width(), clipRect.height()); clipRect.width(), clipRect.height());
} }
@Override
public int requestBitmap(Rect clipRect, float scaleFactor, Callback<Bitmap> bitmapCallback,
Runnable errorCallback) {
return requestBitmap(null, clipRect, scaleFactor, bitmapCallback, errorCallback);
}
@Override @Override
public boolean cancelBitmapRequest(int requestId) { public boolean cancelBitmapRequest(int requestId) {
if (mNativePlayerCompositorDelegate == 0) { if (mNativePlayerCompositorDelegate == 0) {
...@@ -136,8 +145,8 @@ class PlayerCompositorDelegateImpl implements PlayerCompositorDelegate { ...@@ -136,8 +145,8 @@ class PlayerCompositorDelegateImpl implements PlayerCompositorDelegate {
@NativeMethods @NativeMethods
interface Natives { interface Natives {
long initialize(PlayerCompositorDelegateImpl caller, long nativePaintPreviewBaseService, long initialize(PlayerCompositorDelegateImpl caller, long nativePaintPreviewBaseService,
String urlSpec, String directoryKey, Callback<Integer> compositorErrorCallback, byte[] proto, String urlSpec, String directoryKey, boolean mainFrameMode,
boolean isLowMemory); Callback<Integer> compositorErrorCallback, boolean isLowMemory);
void destroy(long nativePlayerCompositorDelegateAndroid); void destroy(long nativePlayerCompositorDelegateAndroid);
int requestBitmap(long nativePlayerCompositorDelegateAndroid, UnguessableToken frameGuid, int requestBitmap(long nativePlayerCompositorDelegateAndroid, UnguessableToken frameGuid,
Callback<Bitmap> bitmapCallback, Runnable errorCallback, float scaleFactor, Callback<Bitmap> bitmapCallback, Runnable errorCallback, float scaleFactor,
......
...@@ -13,10 +13,13 @@ import android.view.ViewGroup.LayoutParams; ...@@ -13,10 +13,13 @@ import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import org.chromium.base.Callback;
import org.chromium.base.TraceEvent; import org.chromium.base.TraceEvent;
import org.chromium.base.UnguessableToken; import org.chromium.base.UnguessableToken;
import org.chromium.components.paint_preview.common.proto.PaintPreview.PaintPreviewProto;
import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider; import org.chromium.components.paintpreview.browser.NativePaintPreviewServiceProvider;
import org.chromium.components.paintpreview.player.frame.PlayerFrameCoordinator; import org.chromium.components.paintpreview.player.frame.PlayerFrameCoordinator;
import org.chromium.url.GURL; import org.chromium.url.GURL;
...@@ -71,7 +74,8 @@ public class PlayerManager { ...@@ -71,7 +74,8 @@ public class PlayerManager {
void onLinkClick(GURL url); void onLinkClick(GURL url);
} }
private static PlayerCompositorDelegate.Factory sCompositorDelegateFactoryForTesting; private static PlayerCompositorDelegate.Factory sCompositorDelegateFactory =
new CompositorDelegateFactory();
private Context mContext; private Context mContext;
private PlayerCompositorDelegate mDelegate; private PlayerCompositorDelegate mDelegate;
...@@ -103,7 +107,7 @@ public class PlayerManager { ...@@ -103,7 +107,7 @@ public class PlayerManager {
mContext = context; mContext = context;
mListener = listener; mListener = listener;
mDelegate = getCompositorDelegateFactory().create(nativePaintPreviewServiceProvider, url, mDelegate = getCompositorDelegateFactory().create(nativePaintPreviewServiceProvider, url,
directoryKey, this::onCompositorReady, mListener::onCompositorError); directoryKey, false, this::onCompositorReady, mListener::onCompositorError);
mHostView = new FrameLayout(mContext); mHostView = new FrameLayout(mContext);
mPlayerSwipeRefreshHandler = mPlayerSwipeRefreshHandler =
new PlayerSwipeRefreshHandler(mContext, mListener::onPullToRefresh); new PlayerSwipeRefreshHandler(mContext, mListener::onPullToRefresh);
...@@ -241,9 +245,29 @@ public class PlayerManager { ...@@ -241,9 +245,29 @@ public class PlayerManager {
return mHostView; return mHostView;
} }
static class CompositorDelegateFactory implements PlayerCompositorDelegate.Factory {
@Override
public PlayerCompositorDelegate create(NativePaintPreviewServiceProvider service, GURL url,
String directoryKey, boolean mainFrameMode,
@NonNull PlayerCompositorDelegate.CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback) {
return new PlayerCompositorDelegateImpl(service, null, url, directoryKey, mainFrameMode,
compositorListener, compositorErrorCallback);
}
@Override
public PlayerCompositorDelegate createForProto(NativePaintPreviewServiceProvider service,
@Nullable PaintPreviewProto proto, GURL url, String directoryKey,
boolean mainFrameMode,
@NonNull PlayerCompositorDelegate.CompositorListener compositorListener,
Callback<Integer> compositorErrorCallback) {
return new PlayerCompositorDelegateImpl(service, proto, url, directoryKey,
mainFrameMode, compositorListener, compositorErrorCallback);
}
}
private PlayerCompositorDelegate.Factory getCompositorDelegateFactory() { private PlayerCompositorDelegate.Factory getCompositorDelegateFactory() {
return (sCompositorDelegateFactoryForTesting != null) ? sCompositorDelegateFactoryForTesting return sCompositorDelegateFactory;
: PlayerCompositorDelegateImpl::new;
} }
@VisibleForTesting @VisibleForTesting
...@@ -254,6 +278,10 @@ public class PlayerManager { ...@@ -254,6 +278,10 @@ public class PlayerManager {
@VisibleForTesting @VisibleForTesting
public static void overrideCompositorDelegateFactoryForTesting( public static void overrideCompositorDelegateFactoryForTesting(
PlayerCompositorDelegate.Factory factory) { PlayerCompositorDelegate.Factory factory) {
sCompositorDelegateFactoryForTesting = factory; if (factory == null) {
sCompositorDelegateFactory = new CompositorDelegateFactory();
return;
}
sCompositorDelegateFactory = factory;
} }
} }
...@@ -193,6 +193,14 @@ public class PlayerFrameMediatorTest { ...@@ -193,6 +193,14 @@ public class PlayerFrameMediatorTest {
return requestId; return requestId;
} }
@Override
public int requestBitmap(Rect clipRect, float scaleFactor, Callback<Bitmap> bitmapCallback,
Runnable errorCallback) {
Assert.fail("The GUIDless version of TestPlayerCompositorDelegate#requestBitmap() "
+ "shouldn't be called.");
return 0;
}
@Override @Override
public boolean cancelBitmapRequest(int requestId) { public boolean cancelBitmapRequest(int requestId) {
return false; return false;
......
...@@ -64,16 +64,18 @@ jlong JNI_PlayerCompositorDelegateImpl_Initialize( ...@@ -64,16 +64,18 @@ jlong JNI_PlayerCompositorDelegateImpl_Initialize(
JNIEnv* env, JNIEnv* env,
const JavaParamRef<jobject>& j_object, const JavaParamRef<jobject>& j_object,
jlong paint_preview_service, jlong paint_preview_service,
const JavaParamRef<jbyteArray>& j_proto,
const JavaParamRef<jstring>& j_url_spec, const JavaParamRef<jstring>& j_url_spec,
const JavaParamRef<jstring>& j_directory_key, const JavaParamRef<jstring>& j_directory_key,
jboolean j_main_frame_mode,
const JavaParamRef<jobject>& j_compositor_error_callback, const JavaParamRef<jobject>& j_compositor_error_callback,
jboolean j_is_low_mem) { jboolean j_is_low_mem) {
PlayerCompositorDelegateAndroid* delegate = PlayerCompositorDelegateAndroid* delegate =
new PlayerCompositorDelegateAndroid( new PlayerCompositorDelegateAndroid(
env, j_object, env, j_object,
reinterpret_cast<PaintPreviewBaseService*>(paint_preview_service), reinterpret_cast<PaintPreviewBaseService*>(paint_preview_service),
j_url_spec, j_directory_key, j_compositor_error_callback, j_proto, j_url_spec, j_directory_key, j_main_frame_mode,
j_is_low_mem); j_compositor_error_callback, j_is_low_mem);
return reinterpret_cast<intptr_t>(delegate); return reinterpret_cast<intptr_t>(delegate);
} }
...@@ -81,18 +83,33 @@ PlayerCompositorDelegateAndroid::PlayerCompositorDelegateAndroid( ...@@ -81,18 +83,33 @@ PlayerCompositorDelegateAndroid::PlayerCompositorDelegateAndroid(
JNIEnv* env, JNIEnv* env,
const JavaParamRef<jobject>& j_object, const JavaParamRef<jobject>& j_object,
PaintPreviewBaseService* paint_preview_service, PaintPreviewBaseService* paint_preview_service,
const JavaParamRef<jbyteArray>& j_proto,
const JavaParamRef<jstring>& j_url_spec, const JavaParamRef<jstring>& j_url_spec,
const JavaParamRef<jstring>& j_directory_key, const JavaParamRef<jstring>& j_directory_key,
jboolean j_main_frame_mode,
const JavaParamRef<jobject>& j_compositor_error_callback, const JavaParamRef<jobject>& j_compositor_error_callback,
jboolean j_is_low_mem) jboolean j_is_low_mem)
: PlayerCompositorDelegate(), : PlayerCompositorDelegate(),
request_id_(0), request_id_(0),
startup_timestamp_(base::TimeTicks::Now()) { startup_timestamp_(base::TimeTicks::Now()) {
if (j_proto) {
std::string serialized_proto;
base::android::JavaByteArrayToString(env, j_proto, &serialized_proto);
auto proto = std::make_unique<PaintPreviewProto>();
if (!proto->ParseFromString(serialized_proto)) {
base::android::RunIntCallbackAndroid(
j_compositor_error_callback,
static_cast<int>(CompositorStatus::PROTOBUF_DESERIALIZATION_ERROR));
return;
}
PlayerCompositorDelegate::SetProto(std::move(proto));
}
PlayerCompositorDelegate::Initialize( PlayerCompositorDelegate::Initialize(
paint_preview_service, paint_preview_service,
GURL(base::android::ConvertJavaStringToUTF8(env, j_url_spec)), GURL(base::android::ConvertJavaStringToUTF8(env, j_url_spec)),
DirectoryKey{ DirectoryKey{
base::android::ConvertJavaStringToUTF8(env, j_directory_key)}, base::android::ConvertJavaStringToUTF8(env, j_directory_key)},
static_cast<bool>(j_main_frame_mode),
base::BindOnce(&base::android::RunIntCallbackAndroid, base::BindOnce(&base::android::RunIntCallbackAndroid,
ScopedJavaGlobalRef<jobject>(j_compositor_error_callback)), ScopedJavaGlobalRef<jobject>(j_compositor_error_callback)),
base::TimeDelta::FromSeconds(15), base::TimeDelta::FromSeconds(15),
...@@ -224,20 +241,23 @@ jint PlayerCompositorDelegateAndroid::RequestBitmap( ...@@ -224,20 +241,23 @@ jint PlayerCompositorDelegateAndroid::RequestBitmap(
TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( TRACE_EVENT_NESTABLE_ASYNC_BEGIN0(
"paint_preview", "PlayerCompositorDelegateAndroid::RequestBitmap", "paint_preview", "PlayerCompositorDelegateAndroid::RequestBitmap",
TRACE_ID_LOCAL(request_id_)); TRACE_ID_LOCAL(request_id_));
gfx::Rect rect(j_clip_x, j_clip_y, j_clip_width, j_clip_height);
int32_t id = PlayerCompositorDelegate::RequestBitmap( auto callback = base::BindOnce(
base::android::UnguessableTokenAndroid::FromJavaUnguessableToken( &PlayerCompositorDelegateAndroid::OnBitmapCallback,
env, j_frame_guid), weak_factory_.GetWeakPtr(),
gfx::Rect(j_clip_x, j_clip_y, j_clip_width, j_clip_height), ScopedJavaGlobalRef<jobject>(j_bitmap_callback),
j_scale_factor, ScopedJavaGlobalRef<jobject>(j_error_callback), request_id_);
base::BindOnce(&PlayerCompositorDelegateAndroid::OnBitmapCallback,
weak_factory_.GetWeakPtr(),
ScopedJavaGlobalRef<jobject>(j_bitmap_callback),
ScopedJavaGlobalRef<jobject>(j_error_callback),
request_id_));
++request_id_; ++request_id_;
return static_cast<jint>(id); base::Optional<base::UnguessableToken> frame_guid;
if (j_frame_guid) {
frame_guid =
base::android::UnguessableTokenAndroid::FromJavaUnguessableToken(
env, j_frame_guid);
}
return static_cast<jint>(PlayerCompositorDelegate::RequestBitmap(
frame_guid, rect, j_scale_factor, std::move(callback)));
} }
jboolean PlayerCompositorDelegateAndroid::CancelBitmapRequest( jboolean PlayerCompositorDelegateAndroid::CancelBitmapRequest(
......
...@@ -21,8 +21,10 @@ class PlayerCompositorDelegateAndroid : public PlayerCompositorDelegate { ...@@ -21,8 +21,10 @@ class PlayerCompositorDelegateAndroid : public PlayerCompositorDelegate {
JNIEnv* env, JNIEnv* env,
const base::android::JavaParamRef<jobject>& j_object, const base::android::JavaParamRef<jobject>& j_object,
PaintPreviewBaseService* paint_preview_service, PaintPreviewBaseService* paint_preview_service,
const base::android::JavaParamRef<jbyteArray>& j_proto,
const base::android::JavaParamRef<jstring>& j_url_spec, const base::android::JavaParamRef<jstring>& j_url_spec,
const base::android::JavaParamRef<jstring>& j_directory_key, const base::android::JavaParamRef<jstring>& j_directory_key,
jboolean j_main_frame_mode,
const base::android::JavaParamRef<jobject>& j_compositor_error_callback, const base::android::JavaParamRef<jobject>& j_compositor_error_callback,
jboolean j_is_low_mem); jboolean j_is_low_mem);
......
...@@ -6,10 +6,11 @@ ...@@ -6,10 +6,11 @@
namespace paint_preview { namespace paint_preview {
BitmapRequest::BitmapRequest(const base::UnguessableToken& frame_guid, BitmapRequest::BitmapRequest(
const gfx::Rect& clip_rect, const base::Optional<base::UnguessableToken>& frame_guid,
float scale_factor, const gfx::Rect& clip_rect,
BitmapRequestCallback callback) float scale_factor,
BitmapRequestCallback callback)
: frame_guid(frame_guid), : frame_guid(frame_guid),
clip_rect(clip_rect), clip_rect(clip_rect),
scale_factor(scale_factor), scale_factor(scale_factor),
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define COMPONENTS_PAINT_PREVIEW_PLAYER_BITMAP_REQUEST_H_ #define COMPONENTS_PAINT_PREVIEW_PLAYER_BITMAP_REQUEST_H_
#include "base/callback.h" #include "base/callback.h"
#include "base/optional.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "components/services/paint_preview_compositor/public/mojom/paint_preview_compositor.mojom.h" #include "components/services/paint_preview_compositor/public/mojom/paint_preview_compositor.mojom.h"
#include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkBitmap.h"
...@@ -18,7 +19,7 @@ struct BitmapRequest { ...@@ -18,7 +19,7 @@ struct BitmapRequest {
base::OnceCallback<void(mojom::PaintPreviewCompositor::BitmapStatus, base::OnceCallback<void(mojom::PaintPreviewCompositor::BitmapStatus,
const SkBitmap&)>; const SkBitmap&)>;
BitmapRequest(const base::UnguessableToken& frame_guid, BitmapRequest(const base::Optional<base::UnguessableToken>& frame_guid,
const gfx::Rect& clip_rect, const gfx::Rect& clip_rect,
float scale_factor, float scale_factor,
BitmapRequestCallback callback); BitmapRequestCallback callback);
...@@ -27,7 +28,7 @@ struct BitmapRequest { ...@@ -27,7 +28,7 @@ struct BitmapRequest {
BitmapRequest& operator=(BitmapRequest&& other) noexcept; BitmapRequest& operator=(BitmapRequest&& other) noexcept;
BitmapRequest(BitmapRequest&& other) noexcept; BitmapRequest(BitmapRequest&& other) noexcept;
base::UnguessableToken frame_guid; base::Optional<base::UnguessableToken> frame_guid;
gfx::Rect clip_rect; gfx::Rect clip_rect;
float scale_factor; float scale_factor;
BitmapRequestCallback callback; BitmapRequestCallback callback;
......
...@@ -117,6 +117,7 @@ void PlayerCompositorDelegate::Initialize( ...@@ -117,6 +117,7 @@ void PlayerCompositorDelegate::Initialize(
PaintPreviewBaseService* paint_preview_service, PaintPreviewBaseService* paint_preview_service,
const GURL& expected_url, const GURL& expected_url,
const DirectoryKey& key, const DirectoryKey& key,
bool main_frame_mode,
base::OnceCallback<void(int)> compositor_error, base::OnceCallback<void(int)> compositor_error,
base::TimeDelta timeout_duration, base::TimeDelta timeout_duration,
size_t max_requests) { size_t max_requests) {
...@@ -141,7 +142,7 @@ void PlayerCompositorDelegate::Initialize( ...@@ -141,7 +142,7 @@ void PlayerCompositorDelegate::Initialize(
&PlayerCompositorDelegate::OnCompositorServiceDisconnected, &PlayerCompositorDelegate::OnCompositorServiceDisconnected,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
InitializeInternal(paint_preview_service, expected_url, key, InitializeInternal(paint_preview_service, expected_url, key, main_frame_mode,
std::move(compositor_error), timeout_duration, std::move(compositor_error), timeout_duration,
max_requests); max_requests);
} }
...@@ -150,6 +151,7 @@ void PlayerCompositorDelegate::InitializeWithFakeServiceForTest( ...@@ -150,6 +151,7 @@ void PlayerCompositorDelegate::InitializeWithFakeServiceForTest(
PaintPreviewBaseService* paint_preview_service, PaintPreviewBaseService* paint_preview_service,
const GURL& expected_url, const GURL& expected_url,
const DirectoryKey& key, const DirectoryKey& key,
bool main_frame_mode,
base::OnceCallback<void(int)> compositor_error, base::OnceCallback<void(int)> compositor_error,
base::TimeDelta timeout_duration, base::TimeDelta timeout_duration,
size_t max_requests, size_t max_requests,
...@@ -160,7 +162,7 @@ void PlayerCompositorDelegate::InitializeWithFakeServiceForTest( ...@@ -160,7 +162,7 @@ void PlayerCompositorDelegate::InitializeWithFakeServiceForTest(
base::BindOnce(&PlayerCompositorDelegate::OnCompositorServiceDisconnected, base::BindOnce(&PlayerCompositorDelegate::OnCompositorServiceDisconnected,
weak_factory_.GetWeakPtr())); weak_factory_.GetWeakPtr()));
InitializeInternal(paint_preview_service, expected_url, key, InitializeInternal(paint_preview_service, expected_url, key, main_frame_mode,
std::move(compositor_error), timeout_duration, std::move(compositor_error), timeout_duration,
max_requests); max_requests);
} }
...@@ -169,10 +171,12 @@ void PlayerCompositorDelegate::InitializeInternal( ...@@ -169,10 +171,12 @@ void PlayerCompositorDelegate::InitializeInternal(
PaintPreviewBaseService* paint_preview_service, PaintPreviewBaseService* paint_preview_service,
const GURL& expected_url, const GURL& expected_url,
const DirectoryKey& key, const DirectoryKey& key,
bool main_frame_mode,
base::OnceCallback<void(int)> compositor_error, base::OnceCallback<void(int)> compositor_error,
base::TimeDelta timeout_duration, base::TimeDelta timeout_duration,
size_t max_requests) { size_t max_requests) {
max_requests_ = max_requests; max_requests_ = max_requests;
main_frame_mode_ = main_frame_mode;
compositor_error_ = std::move(compositor_error); compositor_error_ = std::move(compositor_error);
paint_preview_service_ = paint_preview_service; paint_preview_service_ = paint_preview_service;
key_ = key; key_ = key;
...@@ -199,12 +203,14 @@ void PlayerCompositorDelegate::InitializeInternal( ...@@ -199,12 +203,14 @@ void PlayerCompositorDelegate::InitializeInternal(
} }
int32_t PlayerCompositorDelegate::RequestBitmap( int32_t PlayerCompositorDelegate::RequestBitmap(
const base::UnguessableToken& frame_guid, const base::Optional<base::UnguessableToken>& frame_guid,
const gfx::Rect& clip_rect, const gfx::Rect& clip_rect,
float scale_factor, float scale_factor,
base::OnceCallback<void(mojom::PaintPreviewCompositor::BitmapStatus, base::OnceCallback<void(mojom::PaintPreviewCompositor::BitmapStatus,
const SkBitmap&)> callback) { const SkBitmap&)> callback) {
DCHECK(IsInitialized()); DCHECK(IsInitialized());
DCHECK((main_frame_mode_ && !frame_guid.has_value()) ||
(!main_frame_mode_ && frame_guid.has_value()));
const int32_t request_id = next_request_id_; const int32_t request_id = next_request_id_;
next_request_id_++; next_request_id_++;
if (!paint_preview_compositor_client_) { if (!paint_preview_compositor_client_) {
...@@ -314,10 +320,15 @@ void PlayerCompositorDelegate::OnCompositorClientCreated( ...@@ -314,10 +320,15 @@ void PlayerCompositorDelegate::OnCompositorClientCreated(
TRACE_EVENT_NESTABLE_ASYNC_END0("paint_preview", TRACE_EVENT_NESTABLE_ASYNC_END0("paint_preview",
"PlayerCompositorDelegate CreateCompositor", "PlayerCompositorDelegate CreateCompositor",
TRACE_ID_LOCAL(this)); TRACE_ID_LOCAL(this));
paint_preview_service_->GetFileMixin()->GetCapturedPaintPreviewProto( if (!proto_) {
key, base::nullopt, paint_preview_service_->GetFileMixin()->GetCapturedPaintPreviewProto(
base::BindOnce(&PlayerCompositorDelegate::OnProtoAvailable, key, base::nullopt,
weak_factory_.GetWeakPtr(), expected_url)); base::BindOnce(&PlayerCompositorDelegate::OnProtoAvailable,
weak_factory_.GetWeakPtr(), expected_url));
} else {
OnProtoAvailable(expected_url, PaintPreviewFileMixin::ProtoReadStatus::kOk,
std::move(proto_));
}
} }
void PlayerCompositorDelegate::OnProtoAvailable( void PlayerCompositorDelegate::OnProtoAvailable(
...@@ -394,10 +405,20 @@ void PlayerCompositorDelegate::SendCompositeRequest( ...@@ -394,10 +405,20 @@ void PlayerCompositorDelegate::SendCompositeRequest(
return; return;
} }
paint_preview_compositor_client_->BeginSeparatedFrameComposite( if (main_frame_mode_) {
std::move(begin_composite_request), paint_preview_compositor_client_->BeginMainFrameComposite(
base::BindOnce(&PlayerCompositorDelegate::OnCompositorReadyStatusAdapter, std::move(begin_composite_request),
weak_factory_.GetWeakPtr())); base::BindOnce(
&PlayerCompositorDelegate::OnCompositorReadyStatusAdapter,
weak_factory_.GetWeakPtr()));
} else {
paint_preview_compositor_client_->BeginSeparatedFrameComposite(
std::move(begin_composite_request),
base::BindOnce(
&PlayerCompositorDelegate::OnCompositorReadyStatusAdapter,
weak_factory_.GetWeakPtr()));
}
// Defer building hit testers so it happens in parallel with preparing the // Defer building hit testers so it happens in parallel with preparing the
// compositor. // compositor.
...@@ -437,9 +458,14 @@ void PlayerCompositorDelegate::ProcessBitmapRequestsFromQueue() { ...@@ -437,9 +458,14 @@ void PlayerCompositorDelegate::ProcessBitmapRequestsFromQueue() {
if (!paint_preview_compositor_client_) if (!paint_preview_compositor_client_)
return; return;
paint_preview_compositor_client_->BitmapForSeparatedFrame( if (request.frame_guid.has_value()) {
request.frame_guid, request.clip_rect, request.scale_factor, paint_preview_compositor_client_->BitmapForSeparatedFrame(
std::move(request.callback)); request.frame_guid.value(), request.clip_rect, request.scale_factor,
std::move(request.callback));
} else {
paint_preview_compositor_client_->BitmapForMainFrame(
request.clip_rect, request.scale_factor, std::move(request.callback));
}
pending_bitmap_requests_.erase(it); pending_bitmap_requests_.erase(it);
} }
} }
......
...@@ -49,6 +49,7 @@ class PlayerCompositorDelegate { ...@@ -49,6 +49,7 @@ class PlayerCompositorDelegate {
void Initialize(PaintPreviewBaseService* paint_preview_service, void Initialize(PaintPreviewBaseService* paint_preview_service,
const GURL& url, const GURL& url,
const DirectoryKey& key, const DirectoryKey& key,
bool main_frame_mode,
base::OnceCallback<void(int)> compositor_error, base::OnceCallback<void(int)> compositor_error,
base::TimeDelta timeout_duration, base::TimeDelta timeout_duration,
size_t max_requests); size_t max_requests);
...@@ -56,6 +57,10 @@ class PlayerCompositorDelegate { ...@@ -56,6 +57,10 @@ class PlayerCompositorDelegate {
// Returns whether initialization has happened. // Returns whether initialization has happened.
bool IsInitialized() const { return paint_preview_service_; } bool IsInitialized() const { return paint_preview_service_; }
void SetProto(std::unique_ptr<PaintPreviewProto> proto) {
proto_ = std::move(proto);
}
// Overrides whether to compress the directory when the player is closed. By // Overrides whether to compress the directory when the player is closed. By
// default compression will happen. // default compression will happen.
void SetCompressOnClose(bool compress) { compress_on_close_ = compress; } void SetCompressOnClose(bool compress) { compress_on_close_ = compress; }
...@@ -71,7 +76,7 @@ class PlayerCompositorDelegate { ...@@ -71,7 +76,7 @@ class PlayerCompositorDelegate {
// Pass this ID to `CancelBitmapRequest(int32_t)` to cancel the request if it // Pass this ID to `CancelBitmapRequest(int32_t)` to cancel the request if it
// hasn't already been sent. // hasn't already been sent.
int32_t RequestBitmap( int32_t RequestBitmap(
const base::UnguessableToken& frame_guid, const base::Optional<base::UnguessableToken>& frame_guid,
const gfx::Rect& clip_rect, const gfx::Rect& clip_rect,
float scale_factor, float scale_factor,
base::OnceCallback<void(mojom::PaintPreviewCompositor::BitmapStatus, base::OnceCallback<void(mojom::PaintPreviewCompositor::BitmapStatus,
...@@ -100,6 +105,7 @@ class PlayerCompositorDelegate { ...@@ -100,6 +105,7 @@ class PlayerCompositorDelegate {
PaintPreviewBaseService* paint_preview_service, PaintPreviewBaseService* paint_preview_service,
const GURL& expected_url, const GURL& expected_url,
const DirectoryKey& key, const DirectoryKey& key,
bool main_frame_mode,
base::OnceCallback<void(int)> compositor_error, base::OnceCallback<void(int)> compositor_error,
base::TimeDelta timeout_duration, base::TimeDelta timeout_duration,
size_t max_requests, size_t max_requests,
...@@ -123,6 +129,7 @@ class PlayerCompositorDelegate { ...@@ -123,6 +129,7 @@ class PlayerCompositorDelegate {
void InitializeInternal(PaintPreviewBaseService* paint_preview_service, void InitializeInternal(PaintPreviewBaseService* paint_preview_service,
const GURL& expected_url, const GURL& expected_url,
const DirectoryKey& key, const DirectoryKey& key,
bool main_frame_mode,
base::OnceCallback<void(int)> compositor_error, base::OnceCallback<void(int)> compositor_error,
base::TimeDelta timeout_duration, base::TimeDelta timeout_duration,
size_t max_requests); size_t max_requests);
...@@ -166,6 +173,7 @@ class PlayerCompositorDelegate { ...@@ -166,6 +173,7 @@ class PlayerCompositorDelegate {
base::CancelableOnceClosure timeout_; base::CancelableOnceClosure timeout_;
int max_requests_{1}; int max_requests_{1};
bool main_frame_mode_{false};
base::flat_map<base::UnguessableToken, std::unique_ptr<HitTester>> base::flat_map<base::UnguessableToken, std::unique_ptr<HitTester>>
hit_testers_; hit_testers_;
......
...@@ -137,6 +137,7 @@ void PaintPreviewCompositorImpl::BeginSeparatedFrameComposite( ...@@ -137,6 +137,7 @@ void PaintPreviewCompositorImpl::BeginSeparatedFrameComposite(
// Remove any previously loaded frames, in case |BeginSeparatedFrameComposite| // Remove any previously loaded frames, in case |BeginSeparatedFrameComposite|
// is called multiple times. // is called multiple times.
root_frame_ = nullptr;
frames_.clear(); frames_.clear();
auto response = mojom::PaintPreviewBeginCompositeResponse::New(); auto response = mojom::PaintPreviewBeginCompositeResponse::New();
...@@ -231,11 +232,15 @@ void PaintPreviewCompositorImpl::BeginMainFrameComposite( ...@@ -231,11 +232,15 @@ void PaintPreviewCompositorImpl::BeginMainFrameComposite(
BeginMainFrameCompositeCallback callback) { BeginMainFrameCompositeCallback callback) {
TRACE_EVENT0("paint_preview", TRACE_EVENT0("paint_preview",
"PaintPreviewCompositorImpl::BeginMainFrameComposite"); "PaintPreviewCompositorImpl::BeginMainFrameComposite");
frames_.clear();
auto response = mojom::PaintPreviewBeginCompositeResponse::New();
base::Optional<PaintPreviewProto> paint_preview = base::Optional<PaintPreviewProto> paint_preview =
ParsePaintPreviewProto(request->proto); ParsePaintPreviewProto(request->proto);
if (!paint_preview.has_value()) { if (!paint_preview.has_value()) {
response->root_frame_guid = base::UnguessableToken::Create();
std::move(callback).Run(mojom::PaintPreviewCompositor:: std::move(callback).Run(mojom::PaintPreviewCompositor::
BeginCompositeStatus::kDeserializingFailure); BeginCompositeStatus::kDeserializingFailure,
std::move(response));
return; return;
} }
...@@ -245,8 +250,10 @@ void PaintPreviewCompositorImpl::BeginMainFrameComposite( ...@@ -245,8 +250,10 @@ void PaintPreviewCompositorImpl::BeginMainFrameComposite(
paint_preview->root_frame().embedding_token_low()); paint_preview->root_frame().embedding_token_low());
if (root_frame_guid.is_empty()) { if (root_frame_guid.is_empty()) {
DVLOG(1) << "No valid root frame guid"; DVLOG(1) << "No valid root frame guid";
response->root_frame_guid = base::UnguessableToken::Create();
std::move(callback).Run(mojom::PaintPreviewCompositor:: std::move(callback).Run(mojom::PaintPreviewCompositor::
BeginCompositeStatus::kDeserializingFailure); BeginCompositeStatus::kDeserializingFailure,
std::move(response));
return; return;
} }
...@@ -258,15 +265,31 @@ void PaintPreviewCompositorImpl::BeginMainFrameComposite( ...@@ -258,15 +265,31 @@ void PaintPreviewCompositorImpl::BeginMainFrameComposite(
&recording_map, &subframes_failed); &recording_map, &subframes_failed);
if (root_frame_ == nullptr) { if (root_frame_ == nullptr) {
response->root_frame_guid = base::UnguessableToken::Create();
std::move(callback).Run(mojom::PaintPreviewCompositor:: std::move(callback).Run(mojom::PaintPreviewCompositor::
BeginCompositeStatus::kCompositingFailure); BeginCompositeStatus::kCompositingFailure,
std::move(response));
return; return;
} }
response->root_frame_guid = root_frame_guid;
auto frame_data = mojom::FrameData::New();
SkRect sk_rect = root_frame_->cullRect();
frame_data->scroll_extents = gfx::Size(sk_rect.width(), sk_rect.height());
frame_data->scroll_offsets =
gfx::Size(paint_preview->root_frame().has_scroll_offset_x()
? paint_preview->root_frame().scroll_offset_x()
: 0,
paint_preview->root_frame().has_scroll_offset_y()
? paint_preview->root_frame().scroll_offset_y()
: 0);
response->frames.insert({root_frame_guid, std::move(frame_data)});
std::move(callback).Run( std::move(callback).Run(
subframes_failed subframes_failed
? mojom::PaintPreviewCompositor::BeginCompositeStatus::kPartialSuccess ? mojom::PaintPreviewCompositor::BeginCompositeStatus::kPartialSuccess
: mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess); : mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess,
std::move(response));
} }
void PaintPreviewCompositorImpl::BitmapForMainFrame( void PaintPreviewCompositorImpl::BitmapForMainFrame(
......
...@@ -45,7 +45,7 @@ namespace { ...@@ -45,7 +45,7 @@ namespace {
// then also checks that; // then also checks that;
// - |response->root_frame_guid| == |expected_root_frame_guid| // - |response->root_frame_guid| == |expected_root_frame_guid|
// - |response->subframe_rect_hierarchy| == |expected_data| // - |response->subframe_rect_hierarchy| == |expected_data|
void BeginSeparatedFrameCompositeCallbackImpl( void BeginCompositeCallbackImpl(
mojom::PaintPreviewCompositor::BeginCompositeStatus expected_status, mojom::PaintPreviewCompositor::BeginCompositeStatus expected_status,
const base::UnguessableToken& expected_root_frame_guid, const base::UnguessableToken& expected_root_frame_guid,
const base::flat_map<base::UnguessableToken, mojom::FrameDataPtr>& const base::flat_map<base::UnguessableToken, mojom::FrameDataPtr>&
...@@ -78,12 +78,6 @@ void BeginSeparatedFrameCompositeCallbackImpl( ...@@ -78,12 +78,6 @@ void BeginSeparatedFrameCompositeCallbackImpl(
} }
} }
void BeginMainFrameCompositeCallbackImpl(
mojom::PaintPreviewCompositor::BeginCompositeStatus expected_status,
mojom::PaintPreviewCompositor::BeginCompositeStatus status) {
EXPECT_EQ(status, expected_status);
}
// Checks that |status| == |expected_status|. If |expected_status| == kSuccess, // Checks that |status| == |expected_status|. If |expected_status| == kSuccess,
// then it also checks that |bitmap| and |expected_bitmap| are pixel identical. // then it also checks that |bitmap| and |expected_bitmap| are pixel identical.
void BitmapCallbackImpl( void BitmapCallbackImpl(
...@@ -280,16 +274,22 @@ class PaintPreviewCompositorBeginCompositeTest ...@@ -280,16 +274,22 @@ class PaintPreviewCompositorBeginCompositeTest
case CompositeType::kSeparateFrame: case CompositeType::kSeparateFrame:
compositor_.BeginSeparatedFrameComposite( compositor_.BeginSeparatedFrameComposite(
std::move(request), std::move(request),
base::BindOnce(&BeginSeparatedFrameCompositeCallbackImpl, base::BindOnce(&BeginCompositeCallbackImpl, expected_status,
expected_status, expected_root_frame_guid, expected_root_frame_guid, std::move(expected_data)));
std::move(expected_data)));
break; break;
case CompositeType::kMainFrame: case CompositeType::kMainFrame: {
base::flat_map<base::UnguessableToken, mojom::FrameDataPtr> root_data;
auto it = expected_data.find(expected_root_frame_guid);
if (it != expected_data.end()) {
root_data.insert({expected_root_frame_guid, it->second.Clone()});
root_data.find(expected_root_frame_guid)->second->subframes.clear();
}
compositor_.BeginMainFrameComposite( compositor_.BeginMainFrameComposite(
std::move(request), std::move(request),
base::BindOnce(&BeginMainFrameCompositeCallbackImpl, base::BindOnce(&BeginCompositeCallbackImpl, expected_status,
expected_status)); expected_root_frame_guid, std::move(root_data)));
break; break;
}
default: default:
NOTREACHED(); NOTREACHED();
break; break;
...@@ -592,7 +592,7 @@ TEST(PaintPreviewCompositorTest, TestComposite) { ...@@ -592,7 +592,7 @@ TEST(PaintPreviewCompositorTest, TestComposite) {
compositor.BeginSeparatedFrameComposite( compositor.BeginSeparatedFrameComposite(
std::move(request), std::move(request),
base::BindOnce( base::BindOnce(
&BeginSeparatedFrameCompositeCallbackImpl, &BeginCompositeCallbackImpl,
mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess, mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess,
kRootFrameID, std::move(expected_data))); kRootFrameID, std::move(expected_data)));
float scale_factor = 2; float scale_factor = 2;
...@@ -664,7 +664,7 @@ TEST(PaintPreviewCompositorTest, TestCompositeWithMemoryBuffer) { ...@@ -664,7 +664,7 @@ TEST(PaintPreviewCompositorTest, TestCompositeWithMemoryBuffer) {
compositor.BeginSeparatedFrameComposite( compositor.BeginSeparatedFrameComposite(
std::move(request), std::move(request),
base::BindOnce( base::BindOnce(
&BeginSeparatedFrameCompositeCallbackImpl, &BeginCompositeCallbackImpl,
mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess, mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess,
kRootFrameID, std::move(expected_data))); kRootFrameID, std::move(expected_data)));
float scale_factor = 2; float scale_factor = 2;
...@@ -712,11 +712,9 @@ TEST(PaintPreviewCompositorTest, TestCompositeMainFrameNoDependencies) { ...@@ -712,11 +712,9 @@ TEST(PaintPreviewCompositorTest, TestCompositeMainFrameNoDependencies) {
compositor.BeginMainFrameComposite( compositor.BeginMainFrameComposite(
std::move(request), std::move(request),
base::BindOnce( base::BindOnce(
[](mojom::PaintPreviewCompositor::BeginCompositeStatus status) { &BeginCompositeCallbackImpl,
EXPECT_EQ( mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess,
status, kRootFrameID, std::move(expected_data)));
mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess);
}));
float scale_factor = 2; float scale_factor = 2;
gfx::Rect rect = gfx::ScaleToEnclosingRect( gfx::Rect rect = gfx::ScaleToEnclosingRect(
gfx::Rect(root_frame_scroll_extent), scale_factor); gfx::Rect(root_frame_scroll_extent), scale_factor);
...@@ -764,14 +762,14 @@ TEST(PaintPreviewCompositorTest, TestCompositeMainFrameOneDependency) { ...@@ -764,14 +762,14 @@ TEST(PaintPreviewCompositorTest, TestCompositeMainFrameOneDependency) {
mojom::PaintPreviewBeginCompositeRequest::New(); mojom::PaintPreviewBeginCompositeRequest::New();
request->recording_map = RecordingMapFromPaintPreviewProto(proto); request->recording_map = RecordingMapFromPaintPreviewProto(proto);
request->proto = ToReadOnlySharedMemory(proto); request->proto = ToReadOnlySharedMemory(proto);
expected_data.erase(kSubframe_0_ID);
expected_data.find(kRootFrameID)->second->subframes.clear();
compositor.BeginMainFrameComposite( compositor.BeginMainFrameComposite(
std::move(request), std::move(request),
base::BindOnce( base::BindOnce(
[](mojom::PaintPreviewCompositor::BeginCompositeStatus status) { &BeginCompositeCallbackImpl,
EXPECT_EQ( mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess,
status, kRootFrameID, std::move(expected_data)));
mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess);
}));
float scale_factor = 1; float scale_factor = 1;
gfx::Rect rect = gfx::ScaleToEnclosingRect( gfx::Rect rect = gfx::ScaleToEnclosingRect(
gfx::Rect(root_frame_scroll_extent), scale_factor); gfx::Rect(root_frame_scroll_extent), scale_factor);
...@@ -823,14 +821,14 @@ TEST(PaintPreviewCompositorTest, TestCompositeMainFrameOneDependencyScrolled) { ...@@ -823,14 +821,14 @@ TEST(PaintPreviewCompositorTest, TestCompositeMainFrameOneDependencyScrolled) {
mojom::PaintPreviewBeginCompositeRequest::New(); mojom::PaintPreviewBeginCompositeRequest::New();
request->recording_map = RecordingMapFromPaintPreviewProto(proto); request->recording_map = RecordingMapFromPaintPreviewProto(proto);
request->proto = ToReadOnlySharedMemory(proto); request->proto = ToReadOnlySharedMemory(proto);
expected_data.erase(kSubframe_0_ID);
expected_data.find(kRootFrameID)->second->subframes.clear();
compositor.BeginMainFrameComposite( compositor.BeginMainFrameComposite(
std::move(request), std::move(request),
base::BindOnce( base::BindOnce(
[](mojom::PaintPreviewCompositor::BeginCompositeStatus status) { &BeginCompositeCallbackImpl,
EXPECT_EQ( mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess,
status, kRootFrameID, std::move(expected_data)));
mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess);
}));
float scale_factor = 1; float scale_factor = 1;
gfx::Rect rect = gfx::ScaleToEnclosingRect( gfx::Rect rect = gfx::ScaleToEnclosingRect(
gfx::Rect(root_frame_scroll_extent), scale_factor); gfx::Rect(root_frame_scroll_extent), scale_factor);
...@@ -885,14 +883,14 @@ TEST(PaintPreviewCompositorTest, ...@@ -885,14 +883,14 @@ TEST(PaintPreviewCompositorTest,
mojom::PaintPreviewBeginCompositeRequest::New(); mojom::PaintPreviewBeginCompositeRequest::New();
request->recording_map = RecordingMapFromPaintPreviewProto(proto); request->recording_map = RecordingMapFromPaintPreviewProto(proto);
request->proto = ToReadOnlySharedMemory(proto); request->proto = ToReadOnlySharedMemory(proto);
expected_data.erase(kSubframe_0_ID);
expected_data.find(kRootFrameID)->second->subframes.clear();
compositor.BeginMainFrameComposite( compositor.BeginMainFrameComposite(
std::move(request), std::move(request),
base::BindOnce( base::BindOnce(
[](mojom::PaintPreviewCompositor::BeginCompositeStatus status) { &BeginCompositeCallbackImpl,
EXPECT_EQ( mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess,
status, kRootFrameID, std::move(expected_data)));
mojom::PaintPreviewCompositor::BeginCompositeStatus::kSuccess);
}));
float scale_factor = 1; float scale_factor = 1;
gfx::Rect rect = gfx::Rect rect =
gfx::ScaleToEnclosingRect(root_frame_clip_rect, scale_factor); gfx::ScaleToEnclosingRect(root_frame_clip_rect, scale_factor);
......
...@@ -114,11 +114,10 @@ interface PaintPreviewCompositor { ...@@ -114,11 +114,10 @@ interface PaintPreviewCompositor {
(BitmapStatus status, skia.mojom.BitmapN32? bitmap); (BitmapStatus status, skia.mojom.BitmapN32? bitmap);
// Starts the compositing process for |BitmapForMainFrame| calls using frame // Starts the compositing process for |BitmapForMainFrame| calls using frame
// data |request|. |status| will be negative on failure. If the root frame is // data |request|. On success returns |response| containing metadata
// successfully loaded but subframes fail, |status| will indicate partial // required for UI. |status| will be negative on failure.
// success.
BeginMainFrameComposite(PaintPreviewBeginCompositeRequest request) => BeginMainFrameComposite(PaintPreviewBeginCompositeRequest request) =>
(BeginCompositeStatus status); (BeginCompositeStatus status, PaintPreviewBeginCompositeResponse? response);
// Requests a bitmap of the main frame with sub-frame content included. The // Requests a bitmap of the main frame with sub-frame content included. The
// dimensions and location of the bitmap will match |clip_rect| at scale // dimensions and location of the bitmap will match |clip_rect| at scale
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment