背景
在马哥讲解三分屏实战适配aosp 16时候,最后三分屏运行效果如下:
学员疑问如下:
简单说我们原来设置的圆角,其实都是整个Task四个角都进行设置圆角,这里明显看到Task的左边没有任何圆角,但是右边都是圆角。
那么大家是否有思考过这个是如何实现的么?如果让你去实现你会去如何设计呢?
新api接口讲解:
老版本aosp14上设置圆角接口只有一个
/**
* Sets the corner radius of a {@link SurfaceControl}.
* @param sc SurfaceControl
* @param cornerRadius Corner radius in pixels.
* @return Itself.
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius){
checkPreconditions(sc);
nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius);
returnthis;
}
传递参数也只要核心的一个cornerRadius参数既可以。
但是经过调查发现新版本aosp16上发现一个新的
aosp16版本上 frameworks/base/core/java/android/view/SurfaceControl.java
/**
* Sets the corner radius of a {@link SurfaceControl}. This corner radius is applied to the
* SurfaceControl and its children. The API expects a crop to be set on the SurfaceControl
* to ensure that the corner radius is applied to the correct region. If the crop does not
* intersect with the SurfaceControl's visible content, the corner radius will not be
* applied.
*
* @param sc SurfaceControl
* @param cornerRadius Corner radius in pixels.
* @return Itself.
* @hide
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius){
checkPreconditions(sc);
if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging(
"setCornerRadius", this, sc, "cornerRadius=" + cornerRadius);
}
nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius);
returnthis;
}
/**
* Sets the corner radius for each corner of a {@link SurfaceControl}. This is applied to
* the SurfaceControl and its children. The API expects a crop to be set on the
* SurfaceControl to ensure that the corner radius is applied to the correct region. If the
* crop does not intersect with the SurfaceControl's visible content, the corner radius will
* not be applied.
*
* @param sc SurfaceControl
* @hide
*/
@NonNull
public Transaction setCornerRadius(
SurfaceControl sc, float topLeft, float topRight,
float bottomLeft, float bottomRight){
checkPreconditions(sc);
if (SurfaceControlRegistry.sCallStackDebuggingEnabled) {
SurfaceControlRegistry.getProcessInstance()
.checkCallStackDebugging(
"setCornerRadius",
this,
sc,
"topLeft=" + topLeft
+ " , topRight=" + topRight
+ ", bottomLeft=" + bottomLeft
+ " , bottomRight=" + bottomRight);
}
if (!com.android.graphics.surfaceflinger.flags.Flags.setClientDrawnCornerRadii()) {
Log.w(TAG, "setCornerRadius was called but"
+ "set_client_drawn_corner_radii flag is disabled");
returnthis;
}
nativeSetCornerRadius(mNativeObject, sc.mNativeObject,
topLeft, topRight, bottomLeft, bottomRight);
returnthis;
}
上面可以看出在aosp16明显就有多出一个setCornerRadius接口,可以设置四个角的圆角弧度:
setCornerRadius(
SurfaceControl sc, float topLeft, float topRight,
float bottomLeft, float bottomRight)
这样有了这个接口后,就可以轻易实现对四个圆角轻易控制。
实现源码:
为了简单测试一下这个接口是否生效,看看效果如何,那就对所有的窗口都进行相关的圆角测试:
frameworks/base/services/core/java/com/android/server/wm/WindowStateAnimator.java
private void showRobustly(SurfaceControl.Transaction t) {
//省略部分
//左边的圆角弧度都是50,右边圆角弧度150
t.setCornerRadius(mSurfaceControl,50,150,50,100);
t.setWindowCrop(mSurfaceControl,mWin.mRequestedWidth,mWin.mRequestedHeight);
//省略部分
}
测试结果如下:
测试结果坐标都是弧度为50,右边弧度为150。
留给各位学员作业:
那么请问在SurfaceFlinger中是如何实现对这四个圆角进行单独的弧度设置的?你这边如果自己去实现这个接口你是否有思路呢?然后再结合源码去对比看看哈。
学习fw课程和性能相关知识有啥疑问,请记得联系马哥本人或者在马哥vip群中进行讨论
更多vip干货独享知识,及面试定制指导上岸fw工程师服务,课程优惠购买成为vip学员进入vip群,积极讨论各种行业难点痛点疑难问题,答疑服务等。
请联系马哥微信:

夜雨聆风