Loading core/java/android/view/SurfaceView.java +60 −10 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; import android.text.TextUtils; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; Loading @@ -51,6 +52,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; import android.window.SurfaceSyncGroup; import com.android.graphics.hwui.flags.Flags; import com.android.internal.view.SurfaceCallbackHelper; import java.lang.annotation.Retention; Loading Loading @@ -326,6 +328,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } }; private final boolean mRtDrivenClipping = Flags.clipSurfaceviews(); public SurfaceView(Context context) { this(context, null); } Loading Loading @@ -572,6 +576,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall public void setClipBounds(Rect clipBounds) { super.setClipBounds(clipBounds); if (mRtDrivenClipping && isHardwareAccelerated()) { return; } if (!mClipSurfaceToBounds || mSurfaceControl == null) { return; } Loading Loading @@ -915,6 +923,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } if (sizeChanged || creating || !isHardwareAccelerated()) { if (!mRtDrivenClipping || !isHardwareAccelerated()) { // Set a window crop when creating the surface or changing its size to // crop the buffer to the surface size since the buffer producer may // use SCALING_MODE_SCALE and submit a larger size than the surface Loading @@ -925,6 +934,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth, mSurfaceHeight); } } surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight); Loading @@ -941,7 +951,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/); } if (DEBUG_POSITION) { Log.d(TAG, String.format( Log.d(TAG, TextUtils.formatSimple( "%d performSurfaceTransaction %s " + "position = [%d, %d, %d, %d] surfaceSize = %dx%d", System.identityHashCode(this), Loading Loading @@ -1453,6 +1463,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } private final Rect mRTLastReportedPosition = new Rect(); private final Rect mRTLastSetCrop = new Rect(); private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener { private final int mRtSurfaceWidth; Loading Loading @@ -1495,6 +1506,45 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { try { if (DEBUG_POSITION) { Log.d(TAG, String.format( "%d updateSurfacePosition RenderWorker, frameNr = %d, " + "position = [%d, %d, %d, %d] clip = [%d, %d, %d, %d] " + "surfaceSize = %dx%d", System.identityHashCode(SurfaceView.this), frameNumber, left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom, mRtSurfaceWidth, mRtSurfaceHeight)); } synchronized (mSurfaceControlLock) { if (mSurfaceControl == null) return; mRTLastReportedPosition.set(left, top, right, bottom); onSetSurfacePositionAndScale(mPositionChangedTransaction, mSurfaceControl, mRTLastReportedPosition.left /*positionLeft*/, mRTLastReportedPosition.top /*positionTop*/, mRTLastReportedPosition.width() / (float) mRtSurfaceWidth /*postScaleX*/, mRTLastReportedPosition.height() / (float) mRtSurfaceHeight /*postScaleY*/); mRTLastSetCrop.set(clipLeft, clipTop, clipRight, clipBottom); mPositionChangedTransaction.setCrop(mSurfaceControl, mRTLastSetCrop); if (mRTLastSetCrop.isEmpty()) { mPositionChangedTransaction.hide(mSurfaceControl); } else { mPositionChangedTransaction.show(mSurfaceControl); } } applyOrMergeTransaction(mPositionChangedTransaction, frameNumber); } catch (Exception ex) { Log.e(TAG, "Exception from repositionChild", ex); } } @Override public void applyStretch(long frameNumber, float width, float height, float vecX, float vecY, float maxStretchX, float maxStretchY, Loading graphics/java/android/graphics/RenderNode.java +37 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,17 @@ public final class RenderNode { */ void positionChanged(long frameNumber, int left, int top, int right, int bottom); /** * Called by native by a Rendering Worker thread to update window position; includes * the local rect that represents the clipped area of the RenderNode's bounds. * * @hide */ default void positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { positionChanged(frameNumber, left, top, right, bottom); } /** * Called by JNI * Loading @@ -286,6 +297,23 @@ public final class RenderNode { } } /** * Called by JNI * * @hide */ static boolean callPositionChanged2(WeakReference<PositionUpdateListener> weakListener, long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { final PositionUpdateListener listener = weakListener.get(); if (listener != null) { listener.positionChanged(frameNumber, left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom); return true; } else { return false; } } /** * Call to apply a stretch effect to any child SurfaceControl layers * Loading Loading @@ -370,6 +398,15 @@ public final class RenderNode { } } @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { for (PositionUpdateListener pul : mListeners) { pul.positionChanged(frameNumber, left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom); } } @Override public void positionLost(long frameNumber) { for (PositionUpdateListener pul : mListeners) { Loading libs/hwui/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ cc_defaults { "libsync", "libui", "aconfig_text_flags_c_lib", "server_configurable_flags", ], static_libs: [ "libEGL_blobCache", Loading libs/hwui/DamageAccumulator.cpp +41 −0 Original line number Diff line number Diff line Loading @@ -242,6 +242,47 @@ void DamageAccumulator::applyRenderNodeTransform(DirtyStack* frame) { } } SkRect DamageAccumulator::computeClipAndTransform(const SkRect& bounds, Matrix4* outMatrix) const { const DirtyStack* frame = mHead; Matrix4 transform; SkRect pretransformResult = bounds; while (true) { SkRect currentBounds = pretransformResult; pretransformResult.setEmpty(); switch (frame->type) { case TransformRenderNode: { const RenderProperties& props = frame->renderNode->properties(); // Perform clipping if (props.getClipDamageToBounds() && !currentBounds.isEmpty()) { if (!currentBounds.intersect( SkRect::MakeIWH(props.getWidth(), props.getHeight()))) { currentBounds.setEmpty(); } } // apply all transforms mapRect(props, currentBounds, &pretransformResult); frame->renderNode->applyViewPropertyTransforms(transform); } break; case TransformMatrix4: mapRect(frame->matrix4, currentBounds, &pretransformResult); transform.multiply(*frame->matrix4); break; default: pretransformResult = currentBounds; break; } if (frame->prev == frame) break; frame = frame->prev; } SkRect result; Matrix4 globalToLocal; globalToLocal.loadInverse(transform); mapRect(&globalToLocal, pretransformResult, &result); *outMatrix = transform; return result; } void DamageAccumulator::dirty(float left, float top, float right, float bottom) { mHead->pendingDirty.join({left, top, right, bottom}); } Loading libs/hwui/DamageAccumulator.h +2 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ public: void computeCurrentTransform(Matrix4* outMatrix) const; SkRect computeClipAndTransform(const SkRect& bounds, Matrix4* outMatrix) const; void finish(SkRect* totalDirty); struct StretchResult { Loading Loading
core/java/android/view/SurfaceView.java +60 −10 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.os.SystemClock; import android.text.TextUtils; import android.util.ArraySet; import android.util.AttributeSet; import android.util.Log; Loading @@ -51,6 +52,7 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.IAccessibilityEmbeddedConnection; import android.window.SurfaceSyncGroup; import com.android.graphics.hwui.flags.Flags; import com.android.internal.view.SurfaceCallbackHelper; import java.lang.annotation.Retention; Loading Loading @@ -326,6 +328,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } }; private final boolean mRtDrivenClipping = Flags.clipSurfaceviews(); public SurfaceView(Context context) { this(context, null); } Loading Loading @@ -572,6 +576,10 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall public void setClipBounds(Rect clipBounds) { super.setClipBounds(clipBounds); if (mRtDrivenClipping && isHardwareAccelerated()) { return; } if (!mClipSurfaceToBounds || mSurfaceControl == null) { return; } Loading Loading @@ -915,6 +923,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } if (sizeChanged || creating || !isHardwareAccelerated()) { if (!mRtDrivenClipping || !isHardwareAccelerated()) { // Set a window crop when creating the surface or changing its size to // crop the buffer to the surface size since the buffer producer may // use SCALING_MODE_SCALE and submit a larger size than the surface Loading @@ -925,6 +934,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall surfaceUpdateTransaction.setWindowCrop(mSurfaceControl, mSurfaceWidth, mSurfaceHeight); } } surfaceUpdateTransaction.setDesintationFrame(mBlastSurfaceControl, mSurfaceWidth, mSurfaceHeight); Loading @@ -941,7 +951,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall mScreenRect.height() / (float) mSurfaceHeight /*postScaleY*/); } if (DEBUG_POSITION) { Log.d(TAG, String.format( Log.d(TAG, TextUtils.formatSimple( "%d performSurfaceTransaction %s " + "position = [%d, %d, %d, %d] surfaceSize = %dx%d", System.identityHashCode(this), Loading Loading @@ -1453,6 +1463,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } private final Rect mRTLastReportedPosition = new Rect(); private final Rect mRTLastSetCrop = new Rect(); private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener { private final int mRtSurfaceWidth; Loading Loading @@ -1495,6 +1506,45 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { try { if (DEBUG_POSITION) { Log.d(TAG, String.format( "%d updateSurfacePosition RenderWorker, frameNr = %d, " + "position = [%d, %d, %d, %d] clip = [%d, %d, %d, %d] " + "surfaceSize = %dx%d", System.identityHashCode(SurfaceView.this), frameNumber, left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom, mRtSurfaceWidth, mRtSurfaceHeight)); } synchronized (mSurfaceControlLock) { if (mSurfaceControl == null) return; mRTLastReportedPosition.set(left, top, right, bottom); onSetSurfacePositionAndScale(mPositionChangedTransaction, mSurfaceControl, mRTLastReportedPosition.left /*positionLeft*/, mRTLastReportedPosition.top /*positionTop*/, mRTLastReportedPosition.width() / (float) mRtSurfaceWidth /*postScaleX*/, mRTLastReportedPosition.height() / (float) mRtSurfaceHeight /*postScaleY*/); mRTLastSetCrop.set(clipLeft, clipTop, clipRight, clipBottom); mPositionChangedTransaction.setCrop(mSurfaceControl, mRTLastSetCrop); if (mRTLastSetCrop.isEmpty()) { mPositionChangedTransaction.hide(mSurfaceControl); } else { mPositionChangedTransaction.show(mSurfaceControl); } } applyOrMergeTransaction(mPositionChangedTransaction, frameNumber); } catch (Exception ex) { Log.e(TAG, "Exception from repositionChild", ex); } } @Override public void applyStretch(long frameNumber, float width, float height, float vecX, float vecY, float maxStretchX, float maxStretchY, Loading
graphics/java/android/graphics/RenderNode.java +37 −0 Original line number Diff line number Diff line Loading @@ -271,6 +271,17 @@ public final class RenderNode { */ void positionChanged(long frameNumber, int left, int top, int right, int bottom); /** * Called by native by a Rendering Worker thread to update window position; includes * the local rect that represents the clipped area of the RenderNode's bounds. * * @hide */ default void positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { positionChanged(frameNumber, left, top, right, bottom); } /** * Called by JNI * Loading @@ -286,6 +297,23 @@ public final class RenderNode { } } /** * Called by JNI * * @hide */ static boolean callPositionChanged2(WeakReference<PositionUpdateListener> weakListener, long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { final PositionUpdateListener listener = weakListener.get(); if (listener != null) { listener.positionChanged(frameNumber, left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom); return true; } else { return false; } } /** * Call to apply a stretch effect to any child SurfaceControl layers * Loading Loading @@ -370,6 +398,15 @@ public final class RenderNode { } } @Override public void positionChanged(long frameNumber, int left, int top, int right, int bottom, int clipLeft, int clipTop, int clipRight, int clipBottom) { for (PositionUpdateListener pul : mListeners) { pul.positionChanged(frameNumber, left, top, right, bottom, clipLeft, clipTop, clipRight, clipBottom); } } @Override public void positionLost(long frameNumber) { for (PositionUpdateListener pul : mListeners) { Loading
libs/hwui/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ cc_defaults { "libsync", "libui", "aconfig_text_flags_c_lib", "server_configurable_flags", ], static_libs: [ "libEGL_blobCache", Loading
libs/hwui/DamageAccumulator.cpp +41 −0 Original line number Diff line number Diff line Loading @@ -242,6 +242,47 @@ void DamageAccumulator::applyRenderNodeTransform(DirtyStack* frame) { } } SkRect DamageAccumulator::computeClipAndTransform(const SkRect& bounds, Matrix4* outMatrix) const { const DirtyStack* frame = mHead; Matrix4 transform; SkRect pretransformResult = bounds; while (true) { SkRect currentBounds = pretransformResult; pretransformResult.setEmpty(); switch (frame->type) { case TransformRenderNode: { const RenderProperties& props = frame->renderNode->properties(); // Perform clipping if (props.getClipDamageToBounds() && !currentBounds.isEmpty()) { if (!currentBounds.intersect( SkRect::MakeIWH(props.getWidth(), props.getHeight()))) { currentBounds.setEmpty(); } } // apply all transforms mapRect(props, currentBounds, &pretransformResult); frame->renderNode->applyViewPropertyTransforms(transform); } break; case TransformMatrix4: mapRect(frame->matrix4, currentBounds, &pretransformResult); transform.multiply(*frame->matrix4); break; default: pretransformResult = currentBounds; break; } if (frame->prev == frame) break; frame = frame->prev; } SkRect result; Matrix4 globalToLocal; globalToLocal.loadInverse(transform); mapRect(&globalToLocal, pretransformResult, &result); *outMatrix = transform; return result; } void DamageAccumulator::dirty(float left, float top, float right, float bottom) { mHead->pendingDirty.join({left, top, right, bottom}); } Loading
libs/hwui/DamageAccumulator.h +2 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,8 @@ public: void computeCurrentTransform(Matrix4* outMatrix) const; SkRect computeClipAndTransform(const SkRect& bounds, Matrix4* outMatrix) const; void finish(SkRect* totalDirty); struct StretchResult { Loading