Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

android: fix broken rendering in emulators #31727

Merged
merged 1 commit into from
Mar 18, 2024

Commits on Mar 18, 2024

  1. android: fix broken rendering in emulators

    Android's OpenGL emulation layer (goldfish-opengl) has pre-processing
    logic that looks for samplers of the type `samplerExternalOES` and
    does a simple textual [replacement to change the type][1] to `sampler2D`
    before compilation. It also [marks the sampler][2] as 'replaced' so
    it can emulate the correct type at runtime.
    
    However, this logic can lead to false positives when the sampler is
    declared inside conditional macros. Hence, the sampler's type can be
    incorrectly marked as `samplerExternalOES` even though the #if, #ifdef
    conditional logic would have declared the type as `sampler2D`.
    This seems to be a [known limitation][3].
    
    WebRender (in particular the shared.glsl include) has such conditional
    declaration of the texture units used from the shaders.
    In particular, the sampler [sColor0 here][4] is declared within ifdefs
    to have different types depending on the flags enabled, to allow the
    shader to work with different image target kinds.
    
    WebRender also maintain two versions of the compiled shaders in its cache:
      1. An unoptimized version with all the conditional logic preserved
         in the source until the shader is compiled at runtime on Android,
         when the shader is actually used.
      2. Multiple optimized versions for combinations of features required
         These versions are produced during Servo [build][5]. Thus the
         optimized versions eliminate most of the conditional declarations
         at build time.
    
    The bug in Servo with current code is because, [by default][6], WebRender
    uses the *unoptimized* versions of the shaders. This means the conditional
    GLSL source is evaluated at runtime by the Android emulator and thus ends
    up with the incorrect type for the sColor0 sampler unit, which breaks the
    [texture sampling in the fragment shader][7], causing it to always return
    Vec4(0, 0, 0, 1) and rendering all elements on the page black.
    
    This change forces WebRender to use the *optimized* version as a
    workaround - the optimized versions have unconditional code for the
    sampler declarations so are not susceptible to the emulator issue.
    
    [1]: https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/tags/android-platform-11.0.0_r40/system/GLESv2_enc/GL2Encoder.cpp#1644
    [2]: https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/tags/android-platform-11.0.0_r40/system/GLESv2_enc/GL2Encoder.cpp#1673
    [3]: https://android.googlesource.com/device/generic/goldfish-opengl/+/refs/tags/android-platform-11.0.0_r40/system/GLESv2_enc/GL2Encoder.cpp#1571
    [4]: https://github.com/servo/webrender/blob/b36399019cadcadeeed53759c96870577d4da136/webrender/res/shared.glsl#L206
    [5]: https://github.com/servo/webrender/blob/b36399019cadcadeeed53759c96870577d4da136/webrender/build.rs#L289
    [6]: https://github.com/servo/webrender/blob/b36399019cadcadeeed53759c96870577d4da136/webrender/src/renderer/init.rs#L214
    [7]: https://github.com/servo/webrender/blob/b36399019cadcadeeed53759c96870577d4da136/webrender/res/composite.glsl#L189
    
    Fixes servo#31726.
    
    Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
    mukilan committed Mar 18, 2024
    Configuration menu
    Copy the full SHA
    3fbbb18 View commit details
    Browse the repository at this point in the history