Repository: ManimCommunity/manim
File: manim/renderer/shader.py (Python)

Code before:
        context: Context,
        name: Path | None = None,
        source: dict | None = None,
    ):
        global shader_program_cache
        self.context = context
        self.name = name

        # See if the program is cached.
        if (
            self.name in shader_program_cache
            and shader_program_cache[self.name].ctx == self.context
        ):
            self.shader_program = shader_program_cache[self.name]
        elif source is not None:
            # Generate the shader from inline code if it was passed.
            self.shader_program = context.program(**source)
        else:
            # Search for a file containing the shader.
            source_dict = {}
            source_dict_key = {
                "vert": "vertex_shader",
                "frag": "fragment_shader",
                "geom": "geometry_shader",
            }
            assert name is not None
            shader_folder = SHADER_FOLDER / name
            for shader_file in shader_folder.iterdir():
                shader_file_path = shader_folder / shader_file
                shader_source = get_shader_code_from_file(shader_file_path)
                source_dict[source_dict_key[shader_file_path.stem]] = shader_source
            self.shader_program = context.program(**source_dict)

        # Cache the shader.
        if name is not None and name not in shader_program_cache:
            assert self.name is not None
            shader_program_cache[self.name] = self.shader_program

    def set_uniform(self, name: str, value: Any) -> None:
        with contextlib.suppress(KeyError):
            self.shader_program[name] = value


class FullScreenQuad(Mesh):
    def __init__(
        self,
        context: Context,
        fragment_shader_source: str | None = None,
        fragment_shader_name: str | None = None,
    ):
        if fragment_shader_source is None and fragment_shader_name is None:

Review comment (performance):
In this case, rather than making an assertion, the code should raise an exception if both `name` and `source` happen to be `None`, like `FullScreenQuad` already does. To do so, instead of the assertion, use the `else` clause to test whether `name is not None`.

I suggest referencing `self.source` and `self.name` instead of `source` and `name` to keep consistency with the next suggestion:

```py
        # See if the program is cached.
        if (
            self.name in shader_program_cache
            and shader_program_cache[self.name].ctx == self.context
        ):
            self.shader_program = shader_program_cache[self.name]
        elif self.source is not None:
            # Generate the shader from inline code if it was passed.
            self.shader_program = context.program(**self.source)
        elif self.name is not None:
            # Search for a file containing the shader.
            source_dict = {}
            source_dict_key = {
                "vert": "vertex_shader",
                "frag": "fragment_shader",
                "geom": "geometry_shader",
            }
            shader_folder = SHADER_FOLDER / self.name
            for shader_file in shader_folder.iterdir():
                shader_file_path = shader_folder / shader_file
                shader_source = get_shader_code_from_file(shader_file_path)
                source_dict[source_dict_key[shader_file_path.stem]] = shader_source
            self.shader_program = context.program(**source_dict)
        else:
            raise Exception("Must either pass shader name or shader source.")
```

Code after:
        )
        vertex_array_object.render(self.primitive)
        vertex_buffer_object.release()
        vertex_array_object.release()
        if index_buffer_object is not None:
            index_buffer_object.release()


class Shader:
    def __init__(
        self,
        context: moderngl.Context,
        name: str | None = None,
        source: dict[str, Any] | None = None,
    ):
        global shader_program_cache
        self.context = context
        self.name = name
        self.source = source

        # See if the program is cached.
        if (
            self.name in shader_program_cache
            and shader_program_cache[self.name].ctx == self.context
        ):
            self.shader_program = shader_program_cache[self.name]
        elif self.source is not None:
            # Generate the shader from inline code if it was passed.
            self.shader_program = context.program(**self.source)
        elif self.name is not None:
            # Search for a file containing the shader.
            source_dict = {}
            source_dict_key = {
                "vert": "vertex_shader",
                "frag": "fragment_shader",
                "geom": "geometry_shader",
            }
            shader_folder = SHADER_FOLDER / self.name
            for shader_file in shader_folder.iterdir():
                shader_file_path = shader_folder / shader_file
                shader_source = get_shader_code_from_file(shader_file_path)
                source_dict[source_dict_key[shader_file_path.stem]] = shader_source
            self.shader_program = context.program(**source_dict)
        else:
            raise Exception("Must either pass shader name or shader source.")

        # Cache the shader.
        if self.name is not None and self.name not in shader_program_cache:
            shader_program_cache[self.name] = self.shader_program

    def set_uniform(self, name: str, value: Any) -> None: