import * as twgl from "twgl.js";
import { MFXTransformStream } from "../stream";
import { ExtendedVideoFrame } from "../frame";
import type { Uniform } from "./shaders";
export type BoundTextureTransformer = (gl: WebGL2RenderingContext, type: "frameIn" | "frameOut" | "uniform", key: string, v: WebGLTexture) => void;
export interface Crop {
    x: number;
    y: number;
    width: number;
    height: number;
}
export type Uniforms = Record<string, Uniform<any>> | ((frame: VideoFrame) => Promise<Record<string, Uniform<any>>>);
/** @group Effects */
export interface Effect<T = any> {
    shader: string;
    uniforms?: Record<string, Uniform<T>>;
}
export declare const u: <T>(o: Uniform<T>, frame: ExtendedVideoFrame) => Promise<T>;
export declare class MFXGLHandle {
    frame: VideoFrame;
    context: MFXGLContext;
    textures: number[];
    closed: boolean;
    busy: number;
    isDirty: boolean;
    constructor(frame: VideoFrame, context: MFXGLContext);
    compile(shader: string): twgl.ProgramInfo;
    dirty(): void;
    clean(): void;
    paint(programInfo: twgl.ProgramInfo, uniforms: Uniforms, { transformBoundTexture, }?: {
        transformBoundTexture?: BoundTextureTransformer;
    }): Promise<void>;
    resetBoundTexture(): void;
    close(): ExtendedVideoFrame;
}
export declare class MFXGLContext {
    gl: WebGL2RenderingContext;
    paintProgramInfo: twgl.ProgramInfo;
    bufferInfo: twgl.BufferInfo;
    frameBufferInfo: twgl.FramebufferInfo;
    textureIn: WebGLTexture;
    textureOut: WebGLTexture;
    crop: Crop | null;
    cachedTextures: WeakMap<VideoFrame, WebGLTexture>;
    constructor(width: number, height: number);
    clear(): void;
    setCrop(crop: Crop): void;
    attachTextureToFramebuffer(texture: WebGLTexture): void;
}
export declare class MFXGLEffect extends MFXTransformStream<MFXGLHandle, MFXGLHandle> {
    get identifier(): string;
    constructor(shader: string, uniforms?: Uniforms, { isDirty, transformBoundTexture, transformContext, }?: {
        transformBoundTexture?: BoundTextureTransformer;
        transformContext?: (context: MFXGLContext, frame: VideoFrame) => Promise<void>;
        isDirty?: boolean;
    });
}
/** @group Effects */
export declare class FrameToGL extends MFXTransformStream<ExtendedVideoFrame, MFXGLHandle> {
    get identifier(): string;
    constructor();
}
/** @group Effects */
export declare class GLToFrame extends MFXTransformStream<MFXGLHandle, ExtendedVideoFrame> {
    get identifier(): string;
    constructor(writableStrategy?: QueuingStrategy<MFXGLHandle>, readableStrategy?: QueuingStrategy<ExtendedVideoFrame>);
}
export declare const effect: (input: ReadableStream<VideoFrame>, effects: MFXTransformStream<MFXGLHandle, MFXGLHandle>[][], { trim, writableStrategy, readableStrategy, }?: {
    trim?: {
        start?: number;
        end?: number;
    };
    writableStrategy?: QueuingStrategy<any>;
    readableStrategy?: QueuingStrategy<any>;
}) => ReadableStream<VideoFrame>;
