在 Android 8 及更高版本中,有两个处理图形的功能。SurfaceFlinger 使用 GLES 对某些层进行渲染,并将其他层传递给 Hardware composer 处理。我的问题是,有没有办法让系统只使用 GLES 来渲染一切所以我可以使用着色器(GLSL)代码来正确操作帧缓冲区。
项目文件到处都有 HWC 文件。我试图找到一种方法来改变每一帧。
在 Android 8 及更高版本中,有两个处理图形的功能。SurfaceFlinger 使用 GLES 对某些层进行渲染,并将其他层传递给 Hardware composer 处理。我的问题是,有没有办法让系统只使用 GLES 来渲染一切所以我可以使用着色器(GLSL)代码来正确操作帧缓冲区。
项目文件到处都有 HWC 文件。我试图找到一种方法来改变每一帧。
在Settings->Developer options->HARDWARE ACCELERATED RENDERING
中,有一个开关叫做Disable HW overlays
。如果打开它,系统将关闭HWC
并用于OpenGLES
渲染图层。如果你想永远关闭它,你可以深入代码,找到它设置的标志,然后你可以将它设置为禁用的值HWC
。
更新1:
在DevelopmentSettings.java
,下面的代码是将标志发送到SurfaceFlinger
:
private void writeDisableOverlaysOption() {
try {
IBinder flinger = ServiceManager.getService("SurfaceFlinger");
if (flinger != null) {
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
data.writeInt(disableOverlays);
flinger.transact(1008, data, null, 0);
data.recycle();
updateFlingerOptions();
}
} catch (RemoteException ex) {}
}
在SurfaceFlinger.cpp
中,它会将这个标志保存到mDebugDisableHWC
,并使用下面的代码来通知Layer
用于OpenGLES
强制渲染:
// build the h/w work list
if (CC_UNLIKELY(mGeometryInvalid)) {
mGeometryInvalid = false;
for (size_t dpy = 0; dpy < mDisplays.size(); dpy++) {
sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
const auto hwcId = displayDevice->getHwcDisplayId();
if (hwcId >= 0) {
const Vector<sp<Layer> >& currentLayers(
displayDevice->getVisibleLayersSortedByZ());
for (size_t i = 0; i < currentLayers.size(); i++) {
const auto& layer = currentLayers[i];
if (!layer->hasHwcLayer(hwcId)) {
if (!layer->createHwcLayer(mHwc.get(), hwcId)) {
layer->forceClientComposition(hwcId);
continue;
}
}
layer->setGeometry(displayDevice, i);
if (mDebugDisableHWC || mDebugRegion) {
layer->forceClientComposition(hwcId);
}
}
}
}
}
好的,如果你想通过代码禁用它,你可以写一个类似的方法writeDisableOverlaysOption
,并禁用 switch inSettings
以避免用户使用 switch 重置状态。