0

In Android 8 and above there are two functionalities to handle graphics. SurfaceFlinger uses GLES for some of the layers to render and pass others to handle by Hardware composer. My question is, Is there a way to make the system use only GLES to render everything So I can use the shader(GLSL) code to manipulate frame buffers properly.

The project files has HWC files everywhere. I am trying to find a way to alter each frame.

dhan
  • 63
  • 8

1 Answers1

2

In Settings->Developer options->HARDWARE ACCELERATED RENDERING, there is a switch called Disable HW overlays. If you open it, the system will close the HWC and use OpenGLES to render layers. If you want to close it always, you can dive into the code, and find the flag it sets, and then you can set it to the value to disable HWC.

Update 1:

In DevelopmentSettings.java, below code is to send flag to 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) {}
}

In SurfaceFlinger.cpp, it will save this flag to mDebugDisableHWC, and uses below code to notify Layer to use OpenGLES to render forcibly:

// 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);
                }
            }
        }
    }
}

Okay, if you want to disable it by code, you can write a method like writeDisableOverlaysOption, and disable switch in Settings to avoid user uses switch to reset the state.

utzcoz
  • 649
  • 4
  • 15