This is a strange bug indeed, but I'm sure it's just an emulator bug. It also only occurs when running Android version 7 or earlier in the emulator (which is what
./mach android-emulator and our CI runs do). If you create an AVD with version 8 or later in Android Studio, then you cannot reproduce it.
Bug 1628175 made it so that RGBA surfaces from Canvases are now promoted directly to compositor surfaces. The relevant effect of this is that they now get renderered with the shader
composite_TEXTURE_EXTERNAL rather than
brush_image_TEXTURE_EXTERNAL. The GL errors occur just because of the fact that
composite_TEXTURE_EXTERNAL is bound, even if we comment out actually drawing any triangles with it. They seem to occur when subsequently binding FBOs or uploading data to the GPU cache texture. The problem clearly isn't just because TEXTURE_EXTERNAL is completely broken, because binding
brush_image_TEXTURE_EXTERNAL is fine.
I believe the problem is due to the emulator's emulation of
GL_TEXTURE_EXTERNAL_OES on top of
GL_TEXTURE_2D. When webrender binds a texture to GL_TEXTURE_EXTERNAL_OES, the emulator translates that in to binding to GL_TEXTURE_2D on the host OpenGL implementation. This means it has to do a lot of juggling around of which textures are bound to which target. See here for an example, though I couldn't obviously see where the bug is just by reading the code.
I think the key difference between the composite shader and the brush_image, is that the brush_image shader samples from the GPU cache whereas composite does not. Perhaps for the brush shader we therefore ensure the GPU cache is bound to a certain texture unit (which is not ever used for TEXTURE_EXTERNAL), and this ensures that the GL emulation layer knows the GPU cache texture is a TEXTURE_2D. But in the composite case we don't bind the GPU cache so it skips some bookkeeping. Then when we update the GPU cache, we bind the GPU cache texture to unit 0, which previously had a TEXTURE_EXTERNAL bound to it. It gets confused and thinks the GPU cache texture is a TEXTURE_EXTERNAL, and we get the errors.
That's just a hunch, and I can't say for certain. However, by calling
glBindTexture(GL_TEXTURE_EXERNAL_OES, 0) immediately before any
glBindTexture(GL_TEXTURE_2D, tex), we do indeed avoid the issue.