{"record":{"id":"076bae62bf209ac2","repo":"a-b-street/abstreet","slug":"error-creating-texture","errorCode":null,"errorMessage":"error creating texture: {}","messagePattern":"error creating texture: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"widgetry/src/backend_glow.rs","lineNumber":634,"sourceCode":"                for p in sprite_cell.pixels() {\n                    texture_bytes.extend_from_slice(&p.2 .0);\n                }\n            }\n        }\n\n        Ok(Self {\n            texture_bytes,\n            sprite_width,\n            sprite_height,\n            sprite_count,\n        })\n    }\n\n    // Utilizes `tex_storage_3d` which isn't supported by WebGL 1.0.\n    fn upload_gl2(&self, gl: &glow::Context) -> anyhow::Result<()> {\n        let texture_id = unsafe {\n            gl.create_texture()\n                .map_err(|err| anyhow!(\"error creating texture: {}\", err))?\n        };\n\n        let format = glow::RGBA;\n        let target = glow::TEXTURE_2D_ARRAY;\n        let mipmap_levels: u32 = 2;\n        let internal_format = glow::RGBA;\n\n        unsafe {\n            gl.bind_texture(target, Some(texture_id));\n        }\n\n        // Allocate the storage.\n        unsafe {\n            gl.tex_storage_3d(\n                target,\n                mipmap_levels as i32,\n                internal_format,\n                self.sprite_width as i32,","sourceCodeStart":616,"sourceCodeEnd":652,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/widgetry/src/backend_glow.rs#L616-L652","documentation":"upload_gl2 uploads a texture using OpenGL 2 / WebGL 2 features (tex_storage_3d, TEXTURE_2D_ARRAY). The first step creates a GPU texture via glow's create_texture(); if the driver or context fails to allocate one, the raw backend error is wrapped in this anyhow message. This indicates a low-level GPU/resource failure during texture upload.","triggerScenarios":"upload_texture is called (e.g., for textured triangles or texture arrays) while running on a WebGL 2 / GL 2 context, and gl.create_texture() fails — typically because the GL context is lost or GPU resources are exhausted.","commonSituations":"Browser tab backgrounded/context lost mid-run; too many large textures exhausting GPU memory; buggy or outdated GPU drivers; headless/software rendering environments without proper GL support.","solutions":["Check for GL context loss and recreate the rendering context, then re-upload textures.","Reduce texture count/size (mipmap_levels=2 and RGBA arrays consume memory) to avoid resource exhaustion.","Update GPU/browser drivers or test on different hardware to rule out driver bugs.","Handle the Result from upload_texture and degrade gracefully (e.g., fall back to untextured rendering)."],"exampleFix":"// before\nlet texture_id = unsafe {\n    gl.create_texture()\n        .map_err(|err| anyhow!(\"error creating texture: {}\", err))?\n};\n// after: caller-side graceful fallback\nif let Err(err) = upload_texture(...) {\n    warn!(\"texture upload failed: {}\", err);\n    // fall back to untextured rendering or recreate the context\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Handle texture upload failure with graceful degradation\nif let Err(err) = upload_texture(...) {\n    warn!(\"texture upload failed, continuing without textures: {}\", err);\n    render_untextured_fallback();\n}","preventionTips":["Monitor for GL context loss (webglcontextlost) and re-initialize","Budget texture memory; avoid excessive large RGBA texture arrays","Keep GPU drivers and browsers updated on deployment targets","Test rendering on software GL and headless environments before releases"],"tags":["webgl","gpu","texture","rendering"],"backgroundTag":"module-init-failed","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}