Merge "Fix missing position updates to blur regions" into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
f372925a29
@@ -4196,26 +4196,6 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private void registerFrameDrawingCallbackForBlur() {
|
|
||||||
if (!isHardwareEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final boolean hasBlurUpdates = mBlurRegionAggregator.hasUpdates();
|
|
||||||
final boolean needsCallbackForBlur = hasBlurUpdates || mBlurRegionAggregator.hasRegions();
|
|
||||||
|
|
||||||
if (!needsCallbackForBlur) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final BackgroundBlurDrawable.BlurRegion[] blurRegionsForFrame =
|
|
||||||
mBlurRegionAggregator.getBlurRegionsCopyForRT();
|
|
||||||
|
|
||||||
// The callback will run on the render thread.
|
|
||||||
registerRtFrameCallback((frame) -> mBlurRegionAggregator
|
|
||||||
.dispatchBlurTransactionIfNeeded(frame, blurRegionsForFrame, hasBlurUpdates));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerCallbackForPendingTransactions() {
|
private void registerCallbackForPendingTransactions() {
|
||||||
registerRtFrameCallback(new FrameDrawingCallback() {
|
registerRtFrameCallback(new FrameDrawingCallback() {
|
||||||
@Override
|
@Override
|
||||||
@@ -4253,7 +4233,6 @@ public final class ViewRootImpl implements ViewParent,
|
|||||||
mIsDrawing = true;
|
mIsDrawing = true;
|
||||||
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
|
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "draw");
|
||||||
|
|
||||||
registerFrameDrawingCallbackForBlur();
|
|
||||||
addFrameCommitCallbackIfNeeded();
|
addFrameCommitCallbackIfNeeded();
|
||||||
|
|
||||||
boolean usingAsyncReport = isHardwareEnabled() && mSyncBufferCallback != null;
|
boolean usingAsyncReport = isHardwareEnabled() && mSyncBufferCallback != null;
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import android.util.ArraySet;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.LongSparseArray;
|
import android.util.LongSparseArray;
|
||||||
import android.view.ViewRootImpl;
|
import android.view.ViewRootImpl;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
|
||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.annotations.GuardedBy;
|
import com.android.internal.annotations.GuardedBy;
|
||||||
@@ -232,9 +233,12 @@ public final class BackgroundBlurDrawable extends Drawable {
|
|||||||
private final ArraySet<BackgroundBlurDrawable> mDrawables = new ArraySet();
|
private final ArraySet<BackgroundBlurDrawable> mDrawables = new ArraySet();
|
||||||
@GuardedBy("mRtLock")
|
@GuardedBy("mRtLock")
|
||||||
private final LongSparseArray<ArraySet<Runnable>> mFrameRtUpdates = new LongSparseArray();
|
private final LongSparseArray<ArraySet<Runnable>> mFrameRtUpdates = new LongSparseArray();
|
||||||
|
private long mLastFrameNumber = 0;
|
||||||
|
private BlurRegion[] mLastFrameBlurRegions = null;
|
||||||
private final ViewRootImpl mViewRoot;
|
private final ViewRootImpl mViewRoot;
|
||||||
private BlurRegion[] mTmpBlurRegionsForFrame = new BlurRegion[0];
|
private BlurRegion[] mTmpBlurRegionsForFrame = new BlurRegion[0];
|
||||||
private boolean mHasUiUpdates;
|
private boolean mHasUiUpdates;
|
||||||
|
private ViewTreeObserver.OnPreDrawListener mOnPreDrawListener;
|
||||||
|
|
||||||
public Aggregator(ViewRootImpl viewRoot) {
|
public Aggregator(ViewRootImpl viewRoot) {
|
||||||
mViewRoot = viewRoot;
|
mViewRoot = viewRoot;
|
||||||
@@ -277,6 +281,38 @@ public final class BackgroundBlurDrawable extends Drawable {
|
|||||||
Log.d(TAG, "Remove " + drawable);
|
Log.d(TAG, "Remove " + drawable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mOnPreDrawListener == null && mViewRoot.getView() != null
|
||||||
|
&& hasRegions()) {
|
||||||
|
registerPreDrawListener();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerPreDrawListener() {
|
||||||
|
mOnPreDrawListener = () -> {
|
||||||
|
final boolean hasUiUpdates = hasUpdates();
|
||||||
|
|
||||||
|
if (hasUiUpdates || hasRegions()) {
|
||||||
|
final BlurRegion[] blurRegionsForNextFrame = getBlurRegionsCopyForRT();
|
||||||
|
|
||||||
|
mViewRoot.registerRtFrameCallback(frame -> {
|
||||||
|
synchronized (mRtLock) {
|
||||||
|
mLastFrameNumber = frame;
|
||||||
|
mLastFrameBlurRegions = blurRegionsForNextFrame;
|
||||||
|
handleDispatchBlurTransactionLocked(
|
||||||
|
frame, blurRegionsForNextFrame, hasUiUpdates);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!hasRegions() && mViewRoot.getView() != null) {
|
||||||
|
mViewRoot.getView().getViewTreeObserver()
|
||||||
|
.removeOnPreDrawListener(mOnPreDrawListener);
|
||||||
|
mOnPreDrawListener = null;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
mViewRoot.getView().getViewTreeObserver().addOnPreDrawListener(mOnPreDrawListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from a thread pool
|
// Called from a thread pool
|
||||||
@@ -290,7 +326,14 @@ public final class BackgroundBlurDrawable extends Drawable {
|
|||||||
mFrameRtUpdates.put(frameNumber, frameRtUpdates);
|
mFrameRtUpdates.put(frameNumber, frameRtUpdates);
|
||||||
}
|
}
|
||||||
frameRtUpdates.add(update);
|
frameRtUpdates.add(update);
|
||||||
|
|
||||||
|
if (mLastFrameNumber == frameNumber) {
|
||||||
|
// The transaction for this frame has already been sent, so we have to manually
|
||||||
|
// trigger sending a transaction here in order to apply this position update
|
||||||
|
handleDispatchBlurTransactionLocked(frameNumber, mLastFrameBlurRegions, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -329,29 +372,27 @@ public final class BackgroundBlurDrawable extends Drawable {
|
|||||||
/**
|
/**
|
||||||
* Called on RenderThread.
|
* Called on RenderThread.
|
||||||
*
|
*
|
||||||
* @return all blur regions if there are any ui or position updates for this frame,
|
* @return true if it is necessary to send an update to Sf this frame
|
||||||
* null otherwise
|
|
||||||
*/
|
*/
|
||||||
|
@GuardedBy("mRtLock")
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public float[][] getBlurRegionsToDispatchToSf(long frameNumber,
|
public float[][] getBlurRegionsForFrameLocked(long frameNumber,
|
||||||
BlurRegion[] blurRegionsForFrame, boolean hasUiUpdatesForFrame) {
|
BlurRegion[] blurRegionsForFrame, boolean forceUpdate) {
|
||||||
synchronized (mRtLock) {
|
if (!forceUpdate && (mFrameRtUpdates.size() == 0
|
||||||
if (!hasUiUpdatesForFrame && (mFrameRtUpdates.size() == 0
|
|| mFrameRtUpdates.keyAt(0) > frameNumber)) {
|
||||||
|| mFrameRtUpdates.keyAt(0) > frameNumber)) {
|
return null;
|
||||||
return null;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// mFrameRtUpdates holds position updates coming from a thread pool span from
|
// mFrameRtUpdates holds position updates coming from a thread pool span from
|
||||||
// RenderThread. At this point, all position updates for frame frameNumber should
|
// RenderThread. At this point, all position updates for frame frameNumber should
|
||||||
// have been added to mFrameRtUpdates.
|
// have been added to mFrameRtUpdates.
|
||||||
// Here, we apply all updates for frames <= frameNumber in case some previous update
|
// Here, we apply all updates for frames <= frameNumber in case some previous update
|
||||||
// has been missed. This also protects mFrameRtUpdates from memory leaks.
|
// has been missed. This also protects mFrameRtUpdates from memory leaks.
|
||||||
while (mFrameRtUpdates.size() != 0 && mFrameRtUpdates.keyAt(0) <= frameNumber) {
|
while (mFrameRtUpdates.size() != 0 && mFrameRtUpdates.keyAt(0) <= frameNumber) {
|
||||||
final ArraySet<Runnable> frameUpdates = mFrameRtUpdates.valueAt(0);
|
final ArraySet<Runnable> frameUpdates = mFrameRtUpdates.valueAt(0);
|
||||||
mFrameRtUpdates.removeAt(0);
|
mFrameRtUpdates.removeAt(0);
|
||||||
for (int i = 0; i < frameUpdates.size(); i++) {
|
for (int i = 0; i < frameUpdates.size(); i++) {
|
||||||
frameUpdates.valueAt(i).run();
|
frameUpdates.valueAt(i).run();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,13 +411,13 @@ public final class BackgroundBlurDrawable extends Drawable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called on RenderThread in FrameDrawingCallback.
|
* Dispatch all blur regions if there are any ui or position updates for that frame.
|
||||||
* Dispatch all blur regions if there are any ui or position updates.
|
|
||||||
*/
|
*/
|
||||||
public void dispatchBlurTransactionIfNeeded(long frameNumber,
|
@GuardedBy("mRtLock")
|
||||||
BlurRegion[] blurRegionsForFrame, boolean hasUiUpdatesForFrame) {
|
private void handleDispatchBlurTransactionLocked(long frameNumber, BlurRegion[] blurRegions,
|
||||||
final float[][] blurRegionsArray = getBlurRegionsToDispatchToSf(frameNumber,
|
boolean forceUpdate) {
|
||||||
blurRegionsForFrame, hasUiUpdatesForFrame);
|
float[][] blurRegionsArray =
|
||||||
|
getBlurRegionsForFrameLocked(frameNumber, blurRegions, forceUpdate);
|
||||||
if (blurRegionsArray != null) {
|
if (blurRegionsArray != null) {
|
||||||
mViewRoot.dispatchBlurRegions(blurRegionsArray, frameNumber);
|
mViewRoot.dispatchBlurRegions(blurRegionsArray, frameNumber);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class BlurAggregatorTest {
|
|||||||
drawable.setBlurRadius(TEST_BLUR_RADIUS);
|
drawable.setBlurRadius(TEST_BLUR_RADIUS);
|
||||||
final boolean hasUpdates = mAggregator.hasUpdates();
|
final boolean hasUpdates = mAggregator.hasUpdates();
|
||||||
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
|
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
|
||||||
mAggregator.getBlurRegionsToDispatchToSf(TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
mAggregator.getBlurRegionsForFrameLocked(TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
||||||
return drawable;
|
return drawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ public class BlurAggregatorTest {
|
|||||||
assertEquals(1, blurRegions.length);
|
assertEquals(1, blurRegions.length);
|
||||||
|
|
||||||
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
||||||
mAggregator.getBlurRegionsToDispatchToSf(TEST_FRAME_NUMBER, blurRegions,
|
mAggregator.getBlurRegionsForFrameLocked(TEST_FRAME_NUMBER, blurRegions,
|
||||||
mAggregator.hasUpdates());
|
mAggregator.hasUpdates());
|
||||||
assertEquals(1, blurRegions[0].rect.left);
|
assertEquals(1, blurRegions[0].rect.left);
|
||||||
assertEquals(2, blurRegions[0].rect.top);
|
assertEquals(2, blurRegions[0].rect.top);
|
||||||
@@ -169,7 +169,7 @@ public class BlurAggregatorTest {
|
|||||||
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
|
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
|
||||||
assertEquals(1, blurRegions.length);
|
assertEquals(1, blurRegions.length);
|
||||||
|
|
||||||
float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
||||||
assertNull(blurRegionsForSf);
|
assertNull(blurRegionsForSf);
|
||||||
}
|
}
|
||||||
@@ -182,7 +182,7 @@ public class BlurAggregatorTest {
|
|||||||
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
|
final BlurRegion[] blurRegions = mAggregator.getBlurRegionsCopyForRT();
|
||||||
assertEquals(1, blurRegions.length);
|
assertEquals(1, blurRegions.length);
|
||||||
|
|
||||||
float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
||||||
assertNotNull(blurRegionsForSf);
|
assertNotNull(blurRegionsForSf);
|
||||||
assertEquals(1, blurRegionsForSf.length);
|
assertEquals(1, blurRegionsForSf.length);
|
||||||
@@ -197,7 +197,7 @@ public class BlurAggregatorTest {
|
|||||||
assertEquals(1, blurRegions.length);
|
assertEquals(1, blurRegions.length);
|
||||||
|
|
||||||
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
||||||
float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
||||||
assertNotNull(blurRegionsForSf);
|
assertNotNull(blurRegionsForSf);
|
||||||
assertEquals(1, blurRegionsForSf.length);
|
assertEquals(1, blurRegionsForSf.length);
|
||||||
@@ -216,7 +216,7 @@ public class BlurAggregatorTest {
|
|||||||
assertEquals(1, blurRegions.length);
|
assertEquals(1, blurRegions.length);
|
||||||
|
|
||||||
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
||||||
float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates);
|
TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates);
|
||||||
assertNotNull(blurRegionsForSf);
|
assertNotNull(blurRegionsForSf);
|
||||||
assertEquals(1, blurRegionsForSf.length);
|
assertEquals(1, blurRegionsForSf.length);
|
||||||
@@ -237,19 +237,19 @@ public class BlurAggregatorTest {
|
|||||||
assertEquals(2, blurRegions.length);
|
assertEquals(2, blurRegions.length);
|
||||||
|
|
||||||
// Check that an update in one of the drawables triggers a dispatch of all blur regions
|
// Check that an update in one of the drawables triggers a dispatch of all blur regions
|
||||||
float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
TEST_FRAME_NUMBER, blurRegions, hasUpdates);
|
||||||
assertNotNull(blurRegionsForSf);
|
assertNotNull(blurRegionsForSf);
|
||||||
assertEquals(2, blurRegionsForSf.length);
|
assertEquals(2, blurRegionsForSf.length);
|
||||||
|
|
||||||
// Check that the Aggregator deleted all position updates for frame TEST_FRAME_NUMBER
|
// Check that the Aggregator deleted all position updates for frame TEST_FRAME_NUMBER
|
||||||
blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false);
|
TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false);
|
||||||
assertNull(blurRegionsForSf);
|
assertNull(blurRegionsForSf);
|
||||||
|
|
||||||
// Check that a position update triggers a dispatch of all blur regions
|
// Check that a position update triggers a dispatch of all blur regions
|
||||||
drawable2.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
drawable2.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
||||||
blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates);
|
TEST_FRAME_NUMBER + 1, blurRegions, hasUpdates);
|
||||||
assertNotNull(blurRegionsForSf);
|
assertNotNull(blurRegionsForSf);
|
||||||
assertEquals(2, blurRegionsForSf.length);
|
assertEquals(2, blurRegionsForSf.length);
|
||||||
@@ -292,7 +292,7 @@ public class BlurAggregatorTest {
|
|||||||
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER, 1, 2, 3, 4);
|
||||||
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER + 1, 5, 6, 7, 8);
|
mDrawable.mPositionUpdateListener.positionChanged(TEST_FRAME_NUMBER + 1, 5, 6, 7, 8);
|
||||||
|
|
||||||
final float[][] blurRegionsForSf = mAggregator.getBlurRegionsToDispatchToSf(
|
final float[][] blurRegionsForSf = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false);
|
TEST_FRAME_NUMBER, blurRegions, /* hasUiUpdates= */ false);
|
||||||
assertNotNull(blurRegionsForSf);
|
assertNotNull(blurRegionsForSf);
|
||||||
assertEquals(1, blurRegionsForSf.length);
|
assertEquals(1, blurRegionsForSf.length);
|
||||||
@@ -303,7 +303,7 @@ public class BlurAggregatorTest {
|
|||||||
assertEquals(3f, blurRegionsForSf[0][4]);
|
assertEquals(3f, blurRegionsForSf[0][4]);
|
||||||
assertEquals(4f, blurRegionsForSf[0][5]);
|
assertEquals(4f, blurRegionsForSf[0][5]);
|
||||||
|
|
||||||
final float[][] blurRegionsForSfForNextFrame = mAggregator.getBlurRegionsToDispatchToSf(
|
final float[][] blurRegionsForSfForNextFrame = mAggregator.getBlurRegionsForFrameLocked(
|
||||||
TEST_FRAME_NUMBER + 1, blurRegions, /* hasUiUpdates= */ false);
|
TEST_FRAME_NUMBER + 1, blurRegions, /* hasUiUpdates= */ false);
|
||||||
assertNotNull(blurRegionsForSfForNextFrame);
|
assertNotNull(blurRegionsForSfForNextFrame);
|
||||||
assertEquals(1, blurRegionsForSfForNextFrame.length);
|
assertEquals(1, blurRegionsForSfForNextFrame.length);
|
||||||
|
|||||||
Reference in New Issue
Block a user