Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Impeller] Enable MSAA for OpenGLES: Take 2. (flutter#47030)
Closes flutter/flutter#130045. Continues the work started in flutter#46381. _This is PR supercedes flutter#46688 It's worth calling out the mechanism we're using is only supported in OpenGL 3.0+, so we'll need a different solution (either by default, or when Blit is not available) to get proper device support. I'll file an issue before merging. ## Status Appears to work! I validated it on a local demo app, flutter_gallery, and Wonderous. Example: ![flutter_05](https://github.com/flutter/engine/assets/168174/36f41602-511c-4b62-95d6-e09b56f89566) --- ## Background <details> <summary>History</summary> <br> **Still blocked**, but MSAA is working provided you use a phone with OpenGLES 3.0+. The last bit is getting stencil attachments to work again (they currently crash with a `GL_INVALID_OPERATION`). Compared to flutter#46688, we''ve corrected some incorrect OpenGL calls and assumptions - for example we now have both multi-sampled textures similar to the [`MultisampledFBO.cpp`](https://github.com/ARM-software/opengl-es-sdk-for-android/blob/master/samples/advanced_samples/MultisampledFBO/jni/MultisampledFBO.cpp#L702) example. After doing so, the GL driver is successfully called, and no errors or crashes persist. Yay! We did need to use [`glBlitFramebuffer`](https://registry.khronos.org/OpenGL-Refpages/es3.0/html/glBlitFramebuffer.xhtml) to move from the resolve texture to the color attachment, and referenced some other [example code](https://github.com/VictorGordan/opengl-tutorials/blob/346624ecc5a03f0f6d1d19247db0cc68d21bb7a5/YoutubeOpenGL%2027%20-%20Normal%20Maps/Main.cpp#L274) for that. <details> <summary>Example App</summary> ```dart import 'package:flutter/material.dart'; void main() { runApp(const MainApp()); } class MainApp extends StatefulWidget { const MainApp({super.key}); @OverRide State<MainApp> createState() => _MainAppState(); } class _MainAppState extends State<MainApp> { bool msaa = true; @OverRide Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar( title: const Text('Force offscreen MSAA'), actions: [ Switch( value: msaa, onChanged: (value) { setState(() { msaa = value; }); }, ), ], ), body: Center( child: ForceOffscreenMSAA(opaque: !msaa), ), ), ); } } // Draws 2 overlapping circles (BoxDecoration/BoxShape) wrapped in 50% opacity. class ForceOffscreenMSAA extends StatelessWidget { final bool opaque; const ForceOffscreenMSAA({required this.opaque, super.key}); @OverRide Widget build(BuildContext context) { return Opacity( opacity: opaque ? 1.0 : 0.5, child: const DecoratedBox( decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.red, ), child: SizedBox( width: 300, height: 300, child: DecoratedBox( decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.green, ), ), ), ), ); } } ``` </details> <details> <summary>Screenshots</summary> ![Disabled](https://github.com/flutter/engine/assets/168174/0b00e278-fb8f-468d-b5ae-896341789d3f) ![Enabled](https://github.com/flutter/engine/assets/168174/045d056a-2a23-4a27-be9a-b8fbc3e60fb8) </details> <details> <summary>Open GL Commands during MSAA Render</summary> ```txt glClearStencil(, 0) glDisable(, 3089) glDisable(, 2929) glDisable(, 2960) glDisable(, 2884) glDisable(, 3042) glColorMask(, 1, 1, 1, 1) glClear(, 17664) glPushDebugGroupKHR(, 33354, 1367, 10, Solid Fill) glDisable(, 3042) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 787, 787) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glGenBuffers(, 1, 0x6f9900a578) glBindBuffer(, 34962, 1) glBufferData(, 34962, 4480, , 35044) glUseProgram(, 56) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x0) glUniformMatrix4fv(, 0, 1, 0, 0xb4000070aadbc860) glUniform4fv(, 1, 1, 0xb4000070aadbc8a0) glBindBuffer(, 34963, 1) glDrawElements(, 4, 426, 5123, 0x480) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1369, 10, Solid Fill) glDisable(, 3042) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 787, 787) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 56) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x880) glUniformMatrix4fv(, 0, 1, 0, 0xb4000070aadbd160) glUniform4fv(, 1, 1, 0xb4000070aadbd1a0) glBindBuffer(, 34963, 1) glDrawElements(, 4, 426, 5123, 0xd00) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glDiscardFramebufferEXT(, 36160, 3, 0xb4000071cad5b590) glBindFramebuffer(, 36160, 0) glDeleteFramebuffers(, 1, 0x6f9900b25c) glPopDebugGroupKHR() glDeleteBuffers(, 1, 0x6f9900ce98) glDebugMessageControlKHR(, 4352, 4352, 4352, 0, nullptr, 1) glPushDebugGroupKHR(, 33354, 1370, 39, EntityPass Render Pass: Depth=0 Count=0) glClearColor(, 1, 0.984314, 0.996078, 1) glClearStencil(, 0) glDisable(, 3089) glDisable(, 2929) glDisable(, 2960) glDisable(, 2884) glDisable(, 3042) glColorMask(, 1, 1, 1, 1) glClear(, 17664) glPushDebugGroupKHR(, 33354, 1371, 21, Texture Fill: Subpass) glEnable(, 3042) glBlendFuncSeparate(, 1, 771, 1, 771) glBlendEquationSeparate(, 32774, 32774) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glGenBuffers(, 1, 0x6f9900bfc8) glBindBuffer(, 34962, 1) glBufferData(, 34962, 11360, , 35044) glUseProgram(, 57) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 16, 0x0) glEnableVertexAttribArray(, 1) glVertexAttribPointer(, 1, 2, 5126, 0, 16, 0x8) glUniformMatrix4fv(, 1, 1, 0, 0xb40000705ad2f200) glUniform1fv(, 2, 1, 0xb40000705ad2f240) glUniform1fv(, 3, 1, 0xb40000705ad2f244) glActiveTexture(, 33984) glBindTexture(, 3553, 1) glTexParameteri(, 3553, 10241, 9728) glTexParameteri(, 3553, 10240, 9728) glTexParameteri(, 3553, 10242, 33071) glTexParameteri(, 3553, 10243, 33071) glUniform1i(, 0, 0) glDrawArrays(, 5, 0, 4) glDisableVertexAttribArray(, 0) glDisableVertexAttribArray(, 1) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1373, 10, Solid Fill) glDisable(, 3042) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 58) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x180) glUniformMatrix4fv(, 0, 1, 0, 0xb40000705ad2f300) glUniform4fv(, 1, 1, 0xb40000705ad2f340) glDrawArrays(, 5, 0, 4) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1374, 14, Intersect Clip) glEnable(, 3042) glBlendFuncSeparate(, 0, 1, 0, 1) glBlendEquationSeparate(, 32774, 32774) glColorMask(, glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7682) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 59) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x280) glUniformMatrix4fv(, 0, 1, 0, 0xb40000705ad2f400) glDrawArrays(, 5, 0, 4) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1375, 9, TextFrame) glEnable(, 3042) glBlendFuncSeparate(, 1, 771, 1, 771) glBlendEquationSeparate(, 32774, 32774) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 1, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 60) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 4, 5126, 0, 48, 0x4c0) glEnableVertexAttribArray(, 3) glVertexAttribPointer(, 3, 2, 5126, 0, 48, 0x4e8) glEnableVertexAttribArray(, 1) glVertexAttribPointer(, 1, 4, 5126, 0, 48, 0x4d0) glEnableVertexAttribArray(, 2) glVertexAttribPointer(, 2, 2, 5126, 0, 48, 0x4e0) glUniformMatrix4fv(, 1, 1, 0, 0xb40000705ad2f500) glUniformMatrix4fv(, 2, 1, 0, 0xb40000705ad2f540) glUniform2fv(, 3, 1, 0xb40000705ad2f580) glUniform2fv(, 4, 1, 0xb40000705ad2f588) glUniform4fv(, 5, 1, 0xb40000705ad2f590) glUniform1fv(, 6, 1, 0xb40000705ad2f5a0) glActiveTexture(, 33984) glBindTexture(, 3553, 2) glTexParameteri(, 3553, 10241, 9728) glTexParameteri(, 3553, 10240, 9728) glTexParameteri(, 3553, 10242, 33071) glTexParameteri(, 3553, 10243, 33071) glUniform1i(, 0, 0) glDrawArrays(, 4, 0, 120) glDisableVertexAttribArray(, 0) glDisableVertexAttribArray(, 3) glDisableVertexAttribArray(, 1) glDisableVertexAttribArray(, 2) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1376, 10, Solid Fill) glDisable(, 3042) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 1, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 61) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x1b40) glUniformMatrix4fv(, 0, 1, 0, 0xb40000705ad30f00) glUniform4fv(, 1, 1, 0xb40000705ad30f40) glBindBuffer(, 34963, 1) glDrawElements(, 4, 144, 5123, 0x1cd0) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1377, 10, Solid Fill) glDisable(, 3042) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 1, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 61) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x1e80) glUniformMatrix4fv(, 0, 1, 0, 0xb40000705ad31200) glUniform4fv(, 1, 1, 0xb40000705ad31240) glBindBuffer(, 34963, 1) glDrawElements(, 4, 114, 5123, 0x1fc0) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1378, 12, Restore Clip) glEnable(, 3042) glBlendFuncSeparate(, 0, 1, 0, 1) glBlendEquationSeparate(, 32774, 32774) glColorMask(, glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7681) glStencilFuncSeparate(, 1032, 513, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 62) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x2180) glUniformMatrix4fv(, 0, 1, 0, 0xb40000705ad31300) glDrawArrays(, 5, 0, 4) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1379, 12, RRect Shadow) glEnable(, 3042) glBlendFuncSeparate(, 1, 771, 1, 771) glBlendEquationSeparate(, 32774, 32774) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 63) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x2240) glUniformMatrix4fv(, 0, 1, 0, 0xb40000705ad31400) glUniform4fv(, 1, 1, 0xb40000705ad31500) glUniform2fv(, 2, 1, 0xb40000705ad31510) glUniform1fv(, 3, 1, 0xb40000705ad31518) glUniform1fv(, 4, 1, 0xb40000705ad3151c) glDrawArrays(, 5, 0, 4) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1380, 10, Solid Fill) glEnable(, 3042) glBlendFuncSeparate(, 1, 771, 1, 771) glBlendEquationSeparate(, 32774, 32774) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 64) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 2, 5126, 0, 8, 0x2420) glUniformMatrix4fv(, 0, 1, 0, 0xb40000705ad31600) glUniform4fv(, 1, 1, 0xb40000705ad31640) glDrawArrays(, 5, 0, 4) glDisableVertexAttribArray(, 0) glUseProgram(, 0) glPopDebugGroupKHR() glPushDebugGroupKHR(, 33354, 1381, 9, TextFrame) glEnable(, 3042) glBlendFuncSeparate(, 1, 771, 1, 771) glBlendEquationSeparate(, 32774, 32774) glColorMask(, , , , ) glEnable(, 2960) glStencilOpSeparate(, 1032, 7680, 7680, 7680) glStencilFuncSeparate(, 1032, 514, 0, 4294967295) glStencilMaskSeparate(, 1032, 4294967295) glDisable(, 2929) glViewport(, 0, 0, 1080, 2029) glDisable(, 3089) glDisable(, 2884) glFrontFace(, 2304) glBindBuffer(, 34962, 1) glUseProgram(, 60) glEnableVertexAttribArray(, 0) glVertexAttribPointer(, 0, 4, 5126, 0, 48, 0x26c0) glEnableVertexAttribArray(, 3) glVertexAttribPointer(, 3, 2, 5126, 0, 48, 0x26e8) glEnableVertexAttribArray(, 1) glVertexAttribPointer(, 1, 4, 5126, 0, 48, 0x26d0) glEnableVertexAttribArray(, 2) glVertexAttribPointer(, 2, 2, 5126, 0, 48, 0x26e0) glUniformMatrix4fv(, 1, 1, 0, 0xb40000705ad31700) glUniformMatrix4fv(, 2, 1, 0, 0xb40000705ad31740) glUniform2fv(, 3, 1, 0xb40000705ad31780) glUniform2fv(, 4, 1, 0xb40000705ad31788) glUniform4fv(, 5, 1, 0xb40000705ad31790) glUniform1fv(, 6, 1, 0xb40000705ad317a0) glActiveTexture(, 33984) glBindTexture(, 3553, 2) glTexParameteri(, 3553, 10241, 9729) glTexParameteri(, 3553, 10240, 9729) glTexParameteri(, 3553, 10242, 33071) glTexParameteri(, 3553, 10243, 33071) glUniform1i(, 0, 0) glDrawArrays(, 4, 0, 30) glDisableVertexAttribArray(, 0) glDisableVertexAttribArray(, 3) glDisableVertexAttribArray(, 1) glDisableVertexAttribArray(, 2) glUseProgram(, 0) glPopDebugGroupKHR() glDiscardFramebufferEXT(, 36160, 2, 0xb4000071cad5b310) glPopDebugGroupKHR() ``` </details> <details> <summary>AGI Trace</summary> <img width="590" alt="Screenshot 2023-10-17 at 3 21 44 PM" src="https://github.com/flutter/engine/assets/168174/ce9fa65c-9a2b-4b82-9f67-af5373d119c1"> <img width="336" alt="Screenshot 2023-10-17 at 3 21 51 PM" src="https://github.com/flutter/engine/assets/168174/8016029a-ec6d-4c18-b200-50c6485656fa"> </details> ~~As you can see, with MSAA enabled I get a weird mostly-blank artifact (or sometimes entirely blank).~~ UPDATE: FIXED. What we tried (h/t @jonahwilliams): - [x] Using AGI (with the ANGLE adapter, see also [these oddities](https://developer.android.com/agi/troubleshooting#game_failure_after_using_agi)), see [CircleOpacityTrace.gfxtrace.zip](https://github.com/flutter/engine/files/12966311/CircleOpacityTrace.gfxtrace.zip). - [x] Print debugging the commands (see above) - [x] Commenting out `gl.DiscardFramebufferEXT` optimizations - [x] Render Doc (I need to use a Samsung phone old enough to have OpenGLES) /cc @jonahwilliams to add anything else ^ </details>
- Loading branch information