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

Webpages not rendering on Android x86 and x86_64 emulators. #31726

Closed
mukilan opened this issue Mar 18, 2024 · 0 comments · Fixed by #31727
Closed

Webpages not rendering on Android x86 and x86_64 emulators. #31726

mukilan opened this issue Mar 18, 2024 · 0 comments · Fixed by #31727
Assignees
Labels
I-bustage The effect of the issue remaining unresolved. P-android Android devices

Comments

@mukilan
Copy link
Member

mukilan commented Mar 18, 2024

Describe the bug:
On Android emulators, all websites, including servo.org, produce just a black screen in Servo. This doesn't happen on real devices and the websites look correct. The logs don't have any obvious errors.

android bug

To Reproduce:

  1. Build Servo for Android - ./mach build --target x86_64-linux-android or ./mach build --target i686-linux-android
  2. Install the APK - ./mach install --target <arch>
  3. Run the app ./mach run --android

Expected output: servo.org homepage is rendered correctly on the emulator.
Actual output: Black screen that covers the whole area of the ServoView widget.

Platform:
Android AVD images for x86 Atom or x86_64 Atom architecture, platform 30 or 33.

@mukilan mukilan added the C-untriaged New issues that haven't been triaged yet label Mar 18, 2024
@mukilan mukilan self-assigned this Mar 18, 2024
@mukilan mukilan added P-android Android devices I-bustage The effect of the issue remaining unresolved. and removed C-untriaged New issues that haven't been triaged yet labels Mar 18, 2024
@mukilan mukilan changed the title Webpages not rendering on Android x86 emulators. Webpages not rendering on Android x86 and x86_64 emulators. Mar 18, 2024
mukilan added a commit to mukilan/servo that referenced this issue Mar 18, 2024
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 added a commit to mukilan/servo that referenced this issue Mar 18, 2024
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>
github-merge-queue bot pushed a commit that referenced this issue Mar 18, 2024
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 #31726.

Signed-off-by: Mukilan Thiyagarajan <mukilan@igalia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-bustage The effect of the issue remaining unresolved. P-android Android devices
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant