.
diff --git a/sparse_strips/vello_hybrid/CHANGELOG.md b/sparse_strips/vello_hybrid/CHANGELOG.md
index fb9270c..4db1029 100644
--- a/sparse_strips/vello_hybrid/CHANGELOG.md
+++ b/sparse_strips/vello_hybrid/CHANGELOG.md
@@ -24,8 +24,7 @@
 
 ### Fixed
 
-- The alphas, encoded paints, gradient and filter data textures of the `webgl` backend are now allocated at creation. Previously a scene without alphas, encoded paints, gradients or filters left the corresponding texture incomplete, which made every draw call that bound it non-renderable and emitted a render warning per draw. (by [@grebmeg][])
-- The `webgl` image atlas now grows without hanging the Android WebView (Mali-G52) GL compositor. Growing from the lazily-allocated 1x1 placeholder (`initial_atlas_count == 0`) now re-specifies the backing store in place on the existing `TEXTURE_2D_ARRAY` instead of allocating a replacement texture and deleting the placeholder, and growing an atlas that already holds data unbinds the atlas and `glFlush`es around the reallocation. Previously, either could hang the compositor mid-session, causing an ANR. (by [@grebmeg][])
+- Fixed a bug in the `webgl` backend that could cause an ANR on Mali-G52 GPUs. (by [@grebmeg][])
 
 ## [0.1.0][] - 2026-07-29
 
diff --git a/sparse_strips/vello_hybrid/src/render/webgl/mod.rs b/sparse_strips/vello_hybrid/src/render/webgl/mod.rs
index ca9c204..d6efc57 100644
--- a/sparse_strips/vello_hybrid/src/render/webgl/mod.rs
+++ b/sparse_strips/vello_hybrid/src/render/webgl/mod.rs
@@ -1284,6 +1284,7 @@
             // texture name is required on Mali-G52 under the Android WebView GL compositor: replacing
             // the stub object mid-session hangs the native compositor, causing an ANR, and flushing
             // around the swap does not help.
+            gl.active_texture(WebGl2RenderingContext::TEXTURE0);
             gl.bind_texture(
                 WebGl2RenderingContext::TEXTURE_2D_ARRAY,
                 Some(&self.resources.atlas_texture_array.texture),
@@ -1302,15 +1303,15 @@
             )
             .unwrap();
             self.resources.atlas_texture_array.size = WebGlTextureSize { width, height };
-            self.resources.atlas_layer_count = required_atlas_count;
-            // Cached FBOs were attached to the 1x1 stub store; drop them so we recreate on next use.
-            self.resources.atlas_render_framebuffer = None;
         } else {
             // Growing an atlas that already holds data: allocate a new, larger `TEXTURE_2D_ARRAY`,
             // copy the existing layers across, then swap. On Mali-G52 under the Android WebView GL
             // compositor, `glFlush`ing after the copy is required before the next composite;
             // otherwise, the compositor hangs and causes an ANR. Unbinding the atlas and flushing
             // before allocation are precautionary.
+            gl.active_texture(WebGl2RenderingContext::TEXTURE0);
+            gl.bind_texture(WebGl2RenderingContext::TEXTURE_2D_ARRAY, None);
+            gl.active_texture(WebGl2RenderingContext::TEXTURE2);
             gl.bind_texture(WebGl2RenderingContext::TEXTURE_2D_ARRAY, None);
             gl.flush();
 
@@ -1320,13 +1321,14 @@
 
             // Replace the old resources (dropping the old array frees its GL texture).
             self.resources.atlas_texture_array = new_atlas_texture_array;
-            self.resources.atlas_layer_count = required_atlas_count;
-            // Cached FBOs were attached to the old texture; drop them so we recreate on next use.
-            self.resources.atlas_render_framebuffer = None;
 
             // This is the critical flush that prevents the Mali-G52 compositor hang.
             gl.flush();
         }
+
+        self.resources.atlas_layer_count = required_atlas_count;
+        // Cached FBOs were attached to the previous store; drop them so we recreate on next use.
+        self.resources.atlas_render_framebuffer = None;
     }
 
     /// Copy texture data from the old atlas texture array to a new one.
@@ -2272,14 +2274,13 @@
 }
 
 /// Create a 1x1 RGBA32UI placeholder texture.
-///
-/// See [`create_placeholder_rgba8_texture`] for why the initial allocation matters.
 fn create_placeholder_rgba32ui_texture(gl: &WebGl2RenderingContext) -> Texture {
     let texture = create_texture(
         gl,
         WebGl2RenderingContext::NEAREST,
         WebGl2RenderingContext::NEAREST,
     );
+    // See `create_placeholder_rgba8_texture` for why the initial allocation matters.
     upload_data_to_rgba32_texture(gl, &texture, &[0; 4], 1, 1);
     texture
 }