0

android: Adaptive refresh rate info to viz

Use reflection to call new Display APIs on Android. Then send the into
to viz, which then leaves them unused in this CL. The code path is
similar to the legacy supported frame rate path, instead of adding to
cross-platform display::Display class.

Bug: 402442892
Change-Id: I0832705ba1006aa848d0060b869ad57e88bf097b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6344854
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: Michael Thiessen <mthiesse@chromium.org>
Commit-Queue: Bo Liu <boliu@chromium.org>
Reviewed-by: Ken Buchanan <kenrb@chromium.org>
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1431877}
This commit is contained in:
Bo Liu
2025-03-12 18:34:44 -07:00
committed by Chromium LUCI CQ
parent 5e6be92924
commit 15828fe46d
15 changed files with 278 additions and 15 deletions

@ -221,6 +221,12 @@ class StubCompositorFrameSink
void ForceImmediateDrawAndSwapIfPossible() override {}
void SetVSyncPaused(bool paused) override {}
void UpdateRefreshRate(float refresh_rate) override {}
void SetAdaptiveRefreshRateInfo(
bool has_support,
float suggested_normal,
float suggested_high,
const std::vector<float>& supported_refresh_rates,
float device_scale_factor) override {}
void SetSupportedRefreshRates(
const std::vector<float>& supported_refresh_rates) override {}
void PreserveChildSurfaceControls() override {}

@ -453,6 +453,15 @@ void RootCompositorFrameSinkImpl::UpdateRefreshRate(float refresh_rate) {
external_begin_frame_source_->UpdateRefreshRate(refresh_rate);
}
void RootCompositorFrameSinkImpl::SetAdaptiveRefreshRateInfo(
bool has_support,
float suggested_normal,
float suggested_high,
const std::vector<float>& supported_refresh_rates,
float device_scale_factor) {
// TODO(crbug.com/402442892): Use this info.
}
void RootCompositorFrameSinkImpl::PreserveChildSurfaceControls() {
display_->PreserveChildSurfaceControls();
}

@ -89,6 +89,12 @@ class VIZ_SERVICE_EXPORT RootCompositorFrameSinkImpl
#if BUILDFLAG(IS_ANDROID)
void SetVSyncPaused(bool paused) override;
void UpdateRefreshRate(float refresh_rate) override;
void SetAdaptiveRefreshRateInfo(
bool has_support,
float suggested_normal,
float suggested_high,
const std::vector<float>& supported_refresh_rates,
float device_scale_factor) override;
void PreserveChildSurfaceControls() override;
void SetSwapCompletionCallbackEnabled(bool enable) override;
#endif // BUILDFLAG(IS_ANDROID)

@ -56,6 +56,7 @@ class MockCompositor : public WindowAndroidCompositor {
void OnUpdateRefreshRate(float refresh_rate) override {}
void OnUpdateSupportedRefreshRates(
const std::vector<float>& supported_refresh_rates) override {}
void OnAdaptiveRefreshRateInfoChanged() override {}
std::unique_ptr<ui::CompositorLock> GetCompositorLock(
base::TimeDelta timeout) override {
return nullptr;

@ -287,6 +287,7 @@ void CompositorImpl::SetRootWindow(gfx::NativeWindow root_window) {
// Attach compositor after `LayerTreeHost` has been created.
root_window->AttachCompositor(this);
OnUpdateOverlayTransform();
OnAdaptiveRefreshRateInfoChanged();
host_->SetRoot(root_window_->GetLayer());
host_->SetViewportRectAndScale(gfx::Rect(size_), root_window_->GetDipScale(),
GenerateLocalSurfaceId());
@ -731,6 +732,20 @@ void CompositorImpl::OnUpdateSupportedRefreshRates(
}
}
void CompositorImpl::OnAdaptiveRefreshRateInfoChanged() {
if (root_window_ && display_private_) {
ui::WindowAndroid::AdaptiveRefreshRateInfo arr_info =
root_window_->adaptive_refresh_rate_info();
display_private_->SetAdaptiveRefreshRateInfo(
arr_info.supports_adaptive_refresh_rate,
arr_info.suggested_frame_rate_normal,
arr_info.suggested_frame_rate_high, arr_info.supported_frame_rates,
display::Screen::GetScreen()
->GetDisplayNearestWindow(root_window_)
.device_scale_factor());
}
}
// WindowAndroid can call this callback
// 1. when display rotation is changed
// 2. when display type is changed in fold device(e.g., main->sub, sub->main),
@ -803,6 +818,7 @@ void CompositorImpl::InitializeVizLayerTreeFrameSink(
display_private_->SetSupportedRefreshRates(
root_window_->GetSupportedRefreshRates());
MaybeUpdateObserveBeginFrame();
OnAdaptiveRefreshRateInfoChanged();
auto frame_sink = cc::slim::FrameSink::Create(
std::move(sink_remote), std::move(client_receiver),

@ -153,6 +153,7 @@ class CONTENT_EXPORT CompositorImpl : public Compositor,
void OnUpdateRefreshRate(float refresh_rate) override;
void OnUpdateSupportedRefreshRates(
const std::vector<float>& supported_refresh_rates) override;
void OnAdaptiveRefreshRateInfoChanged() override;
void OnUpdateOverlayTransform() override;
std::unique_ptr<ui::CompositorLock> GetCompositorLock(
base::TimeDelta timeout) override;

@ -66,6 +66,14 @@ interface DisplayPrivate {
[EnableIf=is_android]
UpdateRefreshRate(float refresh_rate);
// Updates adaptive refresh rate information of the associated Display.
[EnableIf=is_android]
SetAdaptiveRefreshRateInfo(bool has_support,
float suggested_normal,
float suggested_high,
array<float> supported_refresh_rates,
float device_scale_factor);
// Updates the list of refresh rates supported by the associated Display.
[EnableIf=can_set_refresh_rate]
SetSupportedRefreshRates(array<float> refresh_rates);

@ -905,6 +905,7 @@ public class WindowAndroid
getWindowIsWideColorGamut());
WindowAndroidJni.get()
.setVSyncPaused(mNativeWindowAndroid, WindowAndroid.this, mVSyncPaused);
onAdaptiveRefreshRateInfoChanged(mDisplayAndroid.getAdaptiveRefreshRateInfo());
}
return mNativeWindowAndroid;
}
@ -1123,6 +1124,18 @@ public class WindowAndroid
recomputeSupportedRefreshRates();
}
@Override
public void onAdaptiveRefreshRateInfoChanged(DisplayAndroid.AdaptiveRefreshRateInfo arrInfo) {
if (mNativeWindowAndroid == 0) return;
WindowAndroidJni.get()
.onAdaptiveRefreshRateInfoChanged(
mNativeWindowAndroid,
arrInfo.supportsAdaptiveRefreshRate,
arrInfo.suggestedFrameRateNormal,
arrInfo.suggestedFrameRateHigh,
arrInfo.supportedFrameRates);
}
@CalledByNative
public void setWideColorEnabled(boolean enabled) {
// Although this API was added in Android O, it was buggy.
@ -1417,6 +1430,13 @@ public class WindowAndroid
WindowAndroid caller,
float @Nullable [] supportedRefreshRates);
void onAdaptiveRefreshRateInfoChanged(
long nativeWindowAndroid,
boolean supportsAdaptiveRefreshRate,
float suggestedFrameRateNormal,
float suggestedFrameRateHigh,
float @Nullable [] supportedRefreshRates);
void onOverlayTransformUpdated(long nativeWindowAndroid, WindowAndroid caller);
void sendUnfoldLatencyBeginTimestamp(long nativeWindowAndroid, long beginTimestampMs);

@ -18,6 +18,7 @@ import androidx.annotation.RequiresApi;
import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.WeakHashMap;
@ -66,6 +67,38 @@ public class DisplayAndroid {
* @param currentMode the current display mode.
*/
default void onCurrentModeChanged(Display.@Nullable Mode currentMode) {}
default void onAdaptiveRefreshRateInfoChanged(AdaptiveRefreshRateInfo arrInfo) {}
}
public static final class AdaptiveRefreshRateInfo {
public final boolean supportsAdaptiveRefreshRate;
public final float suggestedFrameRateNormal;
public final float suggestedFrameRateHigh;
public final float @Nullable [] supportedFrameRates;
public AdaptiveRefreshRateInfo(
boolean supportsAdaptiveRefreshRate,
float suggestedFrameRateNormal,
float suggestedFrameRateHigh,
float @Nullable [] supportedFrameRates) {
this.supportsAdaptiveRefreshRate = supportsAdaptiveRefreshRate;
this.suggestedFrameRateNormal = suggestedFrameRateNormal;
this.suggestedFrameRateHigh = suggestedFrameRateHigh;
this.supportedFrameRates = supportedFrameRates;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof AdaptiveRefreshRateInfo)) {
return false;
}
AdaptiveRefreshRateInfo other = (AdaptiveRefreshRateInfo) obj;
return supportsAdaptiveRefreshRate == other.supportsAdaptiveRefreshRate
&& suggestedFrameRateNormal == other.suggestedFrameRateNormal
&& suggestedFrameRateHigh == other.suggestedFrameRateHigh
&& Arrays.equals(supportedFrameRates, other.supportedFrameRates);
}
}
private static final DisplayAndroidObserver[] EMPTY_OBSERVER_ARRAY =
@ -92,6 +125,8 @@ public class DisplayAndroid {
private boolean mIsInternal;
protected boolean mIsDisplayWideColorGamut;
protected boolean mIsDisplayServerWideColorGamut;
private AdaptiveRefreshRateInfo mAdaptiveRefreshRateInfo =
new AdaptiveRefreshRateInfo(false, 0.0f, 0.0f, null);
protected static DisplayAndroidManager getManager() {
return DisplayAndroidManager.getInstance();
@ -233,10 +268,13 @@ public class DisplayAndroid {
return mCurrentDisplayMode;
}
public AdaptiveRefreshRateInfo getAdaptiveRefreshRateInfo() {
return mAdaptiveRefreshRateInfo;
}
/**
* Whether or not the display is HDR capable. If false then getHdrMaxLuminanceRatio will always
* return 1.0.
* Package private only because no client needs to access this from java.
* return 1.0. Package private only because no client needs to access this from java.
*/
/* package */ boolean getIsHdr() {
return mIsHdr;
@ -312,7 +350,8 @@ public class DisplayAndroid {
/* supportedModes= */ null,
/* isHdr= */ null,
/* hdrMaxLuminanceRatio= */ null,
/* isInternal= */ null);
/* isInternal= */ null,
/* arrInfo= */ null);
}
/** Update the display to the provided parameters. Null values leave the parameter unchanged. */
@ -334,7 +373,8 @@ public class DisplayAndroid {
@Nullable List<Display.Mode> supportedModes,
@Nullable Boolean isHdr,
@Nullable Float hdrMaxLuminanceRatio,
@Nullable Boolean isInternal) {
@Nullable Boolean isInternal,
@Nullable AdaptiveRefreshRateInfo arrInfo) {
boolean nameChanged = name != null && !name.equals(mName);
boolean boundsChanged = bounds != null && !bounds.equals(mBounds);
boolean insetsChanged = insets != null && !insets.equals(mInsets);
@ -362,6 +402,10 @@ public class DisplayAndroid {
boolean hdrMaxLuminanceRatioChanged =
hdrMaxLuminanceRatio != null && hdrMaxLuminanceRatio != mHdrMaxLuminanceRatio;
boolean isInternalChanged = isInternal != null && mIsInternal != isInternal;
boolean adaptiveRefreshRateInfoChanged =
arrInfo != null
&& (mAdaptiveRefreshRateInfo == null
|| !mAdaptiveRefreshRateInfo.equals(arrInfo));
boolean changed =
nameChanged
|| boundsChanged
@ -377,7 +421,8 @@ public class DisplayAndroid {
|| currentModeChanged
|| isHdrChanged
|| hdrMaxLuminanceRatioChanged
|| isInternalChanged;
|| isInternalChanged
|| adaptiveRefreshRateInfoChanged;
if (!changed) return;
if (nameChanged) mName = name;
@ -401,6 +446,9 @@ public class DisplayAndroid {
if (displayModesChanged) mDisplayModes = supportedModes;
if (currentModeChanged) mCurrentDisplayMode = currentMode;
if (isInternalChanged) mIsInternal = isInternal;
if (adaptiveRefreshRateInfoChanged) {
mAdaptiveRefreshRateInfo = arrInfo;
}
getManager().updateDisplayOnNativeSide(this);
if (rotationChanged) {
@ -433,5 +481,11 @@ public class DisplayAndroid {
o.onCurrentModeChanged(mCurrentDisplayMode);
}
}
if (adaptiveRefreshRateInfoChanged) {
DisplayAndroidObserver[] observers = getObservers();
for (DisplayAndroidObserver o : observers) {
o.onAdaptiveRefreshRateInfoChanged(mAdaptiveRefreshRateInfo);
}
}
}
}

@ -22,6 +22,7 @@ import android.view.WindowInsets;
import android.view.WindowManager;
import androidx.annotation.RequiresApi;
import androidx.core.os.BuildCompat;
import org.chromium.base.BuildInfo;
import org.chromium.base.CommandLine;
@ -34,6 +35,8 @@ import org.chromium.build.annotations.NullMarked;
import org.chromium.build.annotations.Nullable;
import org.chromium.ui.util.XrUtils;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
@ -46,6 +49,62 @@ import java.util.function.Consumer;
// The behavior of observing window configuration changes using ComponentCallbacks is new in S.
private static final boolean USE_CONFIGURATION = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
private static class AdaptiveRefreshRateInfoReflection {
private static final int FRAME_RATE_CATEGORY_NORMAL = 0;
private static final int FRAME_RATE_CATEGORY_HIGH = 1;
private static @Nullable Method sHasArrSupport;
private static @Nullable Method sGetSuggestedFrameRate;
static {
Method hasArrSupport = null;
Method getSuggestedFrameRate = null;
if (BuildCompat.isAtLeastB()) {
try {
hasArrSupport = Display.class.getMethod("hasArrSupport");
getSuggestedFrameRate =
Display.class.getMethod("getSuggestedFrameRate", int.class);
} catch (NoSuchMethodException e) {
Log.w(TAG, "Missing ARR methods", e);
}
sHasArrSupport = hasArrSupport;
sGetSuggestedFrameRate = getSuggestedFrameRate;
}
}
static @Nullable AdaptiveRefreshRateInfo getInfo(Display display) {
if (sHasArrSupport == null || sGetSuggestedFrameRate == null) {
return null;
}
boolean hasArrSupport = false;
float suggestedFrameRateNormal = 0.0f;
float suggestedFrameRateHigh = 0.0f;
float[] supportedFrameRates = null;
try {
hasArrSupport = (Boolean) sHasArrSupport.invoke(display);
if (hasArrSupport) {
suggestedFrameRateNormal =
(Float)
sGetSuggestedFrameRate.invoke(
display, FRAME_RATE_CATEGORY_NORMAL);
suggestedFrameRateHigh =
(Float)
sGetSuggestedFrameRate.invoke(
display, FRAME_RATE_CATEGORY_HIGH);
supportedFrameRates = display.getSupportedRefreshRates();
}
} catch (InvocationTargetException | IllegalAccessException e) {
Log.w(TAG, "Invoke ARR methods error", e);
return new AdaptiveRefreshRateInfo(false, 0.0f, 0.0f, null);
}
return new AdaptiveRefreshRateInfo(
hasArrSupport,
suggestedFrameRateNormal,
suggestedFrameRateHigh,
supportedFrameRates);
}
}
// When this object exists, a positive value means that the forced DIP scale is set and
// the zero means it is not. The non existing object (i.e. null reference) means that
// the existence and value of the forced DIP scale has not yet been determined.
@ -307,7 +366,8 @@ import java.util.function.Consumer;
/* supportedModes= */ null,
isHdr(mDisplay),
getHdrSdrRatio(mDisplay),
/* isInternal= */ null);
/* isInternal= */ null,
/* arrInfo= */ null);
}
private void updateCommon(
@ -346,6 +406,11 @@ import java.util.function.Consumer;
}
}
AdaptiveRefreshRateInfo arrInfo = null;
if (BuildCompat.isAtLeastB()) {
arrInfo = AdaptiveRefreshRateInfoReflection.getInfo(display);
}
super.update(
display.getName(),
bounds,
@ -363,6 +428,7 @@ import java.util.function.Consumer;
supportedModes,
isHdr(display),
getHdrSdrRatio(display),
isInternal);
isInternal,
arrInfo);
}
}

@ -58,10 +58,10 @@ public class DisplayAndroidTest {
// Put DisplayAndroid in a known initial state.
mDisplay.addObserver(mObserver);
List<Display.Mode> defaultDisplayModes = Lists.newArrayList(mMode);
updateDisplayWithSupportedModes(defaultDisplayModes);
updateDisplayWithSupportedModes(defaultDisplayModes, /* arrInfo= */ null);
reset(mObserver);
updateDisplayWithSupportedModes(null);
updateDisplayWithSupportedModes(null, /* arrInfo= */ null);
verifyNoInteractions(mObserver);
}
@ -71,11 +71,11 @@ public class DisplayAndroidTest {
// Put DisplayAndroid in a known initial state.
mDisplay.addObserver(mObserver);
List<Display.Mode> defaultDisplayModes = Lists.newArrayList(mMode);
updateDisplayWithSupportedModes(defaultDisplayModes);
updateDisplayWithSupportedModes(defaultDisplayModes, /* arrInfo= */ null);
reset(mObserver);
List<Display.Mode> equalDisplayModes = Lists.newArrayList(mMode);
updateDisplayWithSupportedModes(equalDisplayModes);
updateDisplayWithSupportedModes(equalDisplayModes, /* arrInfo= */ null);
verifyNoInteractions(mObserver);
}
@ -85,17 +85,32 @@ public class DisplayAndroidTest {
// Put DisplayAndroid in a known initial state.
mDisplay.addObserver(mObserver);
List<Display.Mode> defaultDisplayModes = Lists.newArrayList(mMode);
updateDisplayWithSupportedModes(defaultDisplayModes);
updateDisplayWithSupportedModes(defaultDisplayModes, /* arrInfo= */ null);
reset(mObserver);
List<Display.Mode> differentDisplayModes = Lists.newArrayList(mMode, mMode);
updateDisplayWithSupportedModes(differentDisplayModes);
updateDisplayWithSupportedModes(differentDisplayModes, /* arrInfo= */ null);
verify(mObserver).onDisplayModesChanged(differentDisplayModes);
verifyNoMoreInteractions(mObserver);
}
private void updateDisplayWithSupportedModes(@Nullable List<Display.Mode> supportedModes) {
@Test
public void testUpdate_arrInfo() {
// Put DisplayAndroid in a known initial state.
mDisplay.addObserver(mObserver);
DisplayAndroid.AdaptiveRefreshRateInfo arrInfo =
new DisplayAndroid.AdaptiveRefreshRateInfo(
true, 60.0f, 120.0f, new float[] {60.0f, 120.0f});
updateDisplayWithSupportedModes(null, arrInfo);
verify(mObserver).onAdaptiveRefreshRateInfoChanged(arrInfo);
verifyNoMoreInteractions(mObserver);
}
private void updateDisplayWithSupportedModes(
@Nullable List<Display.Mode> supportedModes,
@Nullable DisplayAndroid.AdaptiveRefreshRateInfo arrInfo) {
mDisplay.update(
/* name= */ null,
/* bounds= */ null,
@ -113,6 +128,7 @@ public class DisplayAndroidTest {
supportedModes,
/* isHdr= */ null,
/* hdrMaxLuminanceRatio= */ null,
/* isInternal= */ null);
/* isInternal= */ null,
arrInfo);
}
}

@ -69,6 +69,14 @@ void WindowAndroid::ScopedWindowAndroidForTesting::SetModalDialogManager(
env, window_->GetJavaObject(), modal_dialog_manager);
}
WindowAndroid::AdaptiveRefreshRateInfo::AdaptiveRefreshRateInfo() = default;
WindowAndroid::AdaptiveRefreshRateInfo::AdaptiveRefreshRateInfo(
const AdaptiveRefreshRateInfo& other) = default;
WindowAndroid::AdaptiveRefreshRateInfo::~AdaptiveRefreshRateInfo() = default;
WindowAndroid::AdaptiveRefreshRateInfo&
WindowAndroid::AdaptiveRefreshRateInfo::operator=(
const AdaptiveRefreshRateInfo& other) = default;
// static
WindowAndroid* WindowAndroid::FromJavaWindowAndroid(
const JavaParamRef<jobject>& jwindow_android) {
@ -235,6 +243,27 @@ void WindowAndroid::OnSupportedRefreshRatesUpdated(
compositor_->OnUpdateSupportedRefreshRates(supported_refresh_rates);
}
void WindowAndroid::OnAdaptiveRefreshRateInfoChanged(
JNIEnv* env,
jboolean supports_adaptive_refresh_rate,
jfloat suggested_frame_rate_normal,
jfloat suggested_frame_rate_high,
const base::android::JavaParamRef<jfloatArray>& supported_frame_rates) {
adaptive_refresh_rate_info_.supports_adaptive_refresh_rate =
supports_adaptive_refresh_rate;
adaptive_refresh_rate_info_.suggested_frame_rate_normal =
suggested_frame_rate_normal;
adaptive_refresh_rate_info_.suggested_frame_rate_high =
suggested_frame_rate_high;
if (supported_frame_rates) {
base::android::JavaFloatArrayToFloatVector(
env, supported_frame_rates,
&adaptive_refresh_rate_info_.supported_frame_rates);
} else {
adaptive_refresh_rate_info_.supported_frame_rates.clear();
}
}
void WindowAndroid::OnOverlayTransformUpdated(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj) {

@ -55,6 +55,19 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid {
raw_ptr<WindowAndroid> window_;
};
struct AdaptiveRefreshRateInfo {
bool supports_adaptive_refresh_rate = false;
// Fields below are valid only if `supports_adaptive_refresh_rate` is true.
float suggested_frame_rate_normal = 0.f;
float suggested_frame_rate_high = 0.f;
std::vector<float> supported_frame_rates;
AdaptiveRefreshRateInfo();
AdaptiveRefreshRateInfo(const AdaptiveRefreshRateInfo& other);
~AdaptiveRefreshRateInfo();
AdaptiveRefreshRateInfo& operator=(const AdaptiveRefreshRateInfo& other);
};
static WindowAndroid* FromJavaWindowAndroid(
const base::android::JavaParamRef<jobject>& jwindow_android);
@ -83,6 +96,9 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid {
float GetRefreshRate();
gfx::OverlayTransform GetOverlayTransform();
std::vector<float> GetSupportedRefreshRates();
AdaptiveRefreshRateInfo adaptive_refresh_rate_info() const {
return adaptive_refresh_rate_info_;
}
void SetPreferredRefreshRate(float refresh_rate);
void SetNeedsAnimate();
@ -104,6 +120,12 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid {
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
const base::android::JavaParamRef<jfloatArray>& supported_refresh_rates);
void OnAdaptiveRefreshRateInfoChanged(
JNIEnv* env,
jboolean supports_adaptive_refresh_rate,
jfloat suggested_frame_rate_normal,
jfloat suggested_frame_rate_high,
const base::android::JavaParamRef<jfloatArray>& supported_frame_rates);
void OnOverlayTransformUpdated(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
@ -196,6 +218,8 @@ class UI_ANDROID_EXPORT WindowAndroid : public ViewAndroid {
int selection_handles_active_count_ = 0;
raw_ptr<ViewAndroid> pointer_locking_view_ = nullptr;
AdaptiveRefreshRateInfo adaptive_refresh_rate_info_;
};
} // namespace ui

@ -55,6 +55,7 @@ class UI_ANDROID_EXPORT WindowAndroidCompositor {
virtual void OnUpdateRefreshRate(float refresh_rate) = 0;
virtual void OnUpdateSupportedRefreshRates(
const std::vector<float>& supported_refresh_rates) = 0;
virtual void OnAdaptiveRefreshRateInfoChanged() = 0;
virtual std::unique_ptr<ui::CompositorLock> GetCompositorLock(
base::TimeDelta timeout) = 0;
virtual void OnUpdateOverlayTransform() = 0;

@ -163,6 +163,12 @@ class InProcessContextFactory::PerCompositorData
#if BUILDFLAG(IS_ANDROID)
void SetVSyncPaused(bool paused) override {}
void UpdateRefreshRate(float refresh_rate) override {}
void SetAdaptiveRefreshRateInfo(
bool has_support,
float suggested_normal,
float suggested_high,
const std::vector<float>& supported_refresh_rates,
float device_scale_factor) override {}
void PreserveChildSurfaceControls() override {}
void SetSwapCompletionCallbackEnabled(bool enabled) override {}
#endif // BUILDFLAG(IS_ANDROID)