createTexture method

Future<FlutterAngleTexture> createTexture(
  1. AngleOptions options
)

Implementation

Future<FlutterAngleTexture> createTexture(AngleOptions options) async {
  final height = (options.height * options.dpr).toInt();
  final width = (options.width * options.dpr).toInt();
  late final dynamic result;
  if (_useAngle) {
    result = await _channel.invokeMethod('createTextureAngle', {
      "width": width,
      "height": height,
      "useSurfaceProducer": options.useSurfaceProducer
    });
  } else {
    result = await _channel.invokeMethod('createTexture', {
      "width": width,
      "height": height,
      "useSurfaceProducer": options.useSurfaceProducer
    });
  }

  if (Platform.isAndroid) {
    final newTexture = FlutterAngleTexture(
      this,
      result['textureId']! as int,
      result['rbo'] as int? ?? 0,
      Pointer.fromAddress(result['surface'] as int? ?? 0),
      null,
      0,
      result['location'] as int? ?? 0,
      options
    );
    _rawOpenGl.glViewport(0, 0, width, height);

    if (!options.customRenderer) {
      _worker = RenderWorker(newTexture);
    }

    return newTexture;
  }
  else if (_isApple) {
    // Create the EGL surface from IOSurface before creating the texture object
    Pointer<Void>? macIosSurface;
    if (result.containsKey('surfacePointer')) {
      final surfacePointer = result['surfacePointer'] as int;
      if (surfacePointer != 0) {
        final ioSurfacePtr = Pointer<Void>.fromAddress(surfacePointer);
        macIosSurface = createEGLSurfaceFromIOSurface(ioSurfacePtr, width, height);
        if (macIosSurface == null) {
          angleConsole.error("Failed to create EGL surface from IOSurface");
        } else {
          angleConsole.info("Successfully created EGL surface from IOSurface");
        }
      }
    }

    final newTexture = FlutterAngleTexture(
      this,
      result['textureId']! as int,
      result['rbo'] as int? ?? 0,
      macIosSurface, // We'll use an IOSurface instead
      null,
      0,
      result['location'] as int? ?? 0,
      options
    );

    _rawOpenGl.glViewport(0, 0, width, height);

    if (!options.customRenderer) {
      _worker = RenderWorker(newTexture);
    }

    return newTexture;
  }

  Pointer<Uint32> fbo = calloc();
  _rawOpenGl.glGenFramebuffers(1, fbo);
  _rawOpenGl.glBindFramebuffer(GL_FRAMEBUFFER, fbo.value);

  final newTexture = FlutterAngleTexture(
    this,
    result['textureId']! as int,
    result['rbo'] as int? ?? 0,
    Pointer.fromAddress(result['surface'] as int? ?? 0),
    null,
    fbo.value,
    result['location'] as int? ?? 0,
    options
  );
  angleConsole.info(newTexture.toMap());
  angleConsole.info(_rawOpenGl.glGetError());
  _rawOpenGl.glActiveTexture(WebGL.TEXTURE0);

  _rawOpenGl.glBindRenderbuffer(GL_RENDERBUFFER, newTexture.rboId);
  _rawOpenGl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, newTexture.rboId);

  var frameBufferCheck = _rawOpenGl.glCheckFramebufferStatus(GL_FRAMEBUFFER);
  if (frameBufferCheck != GL_FRAMEBUFFER_COMPLETE) {
    angleConsole.error("Framebuffer (color) check failed: $frameBufferCheck");
  }

  _rawOpenGl.glViewport(0, 0, width, height);

  Pointer<Int32> depthBuffer = calloc();
  _rawOpenGl.glGenRenderbuffers(1, depthBuffer.cast());
  _rawOpenGl.glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer.value);
  _rawOpenGl.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height); //,GL_DEPTH_COMPONENT16//GL_DEPTH24_STENCIL8

  _rawOpenGl.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer.value);

  frameBufferCheck = _rawOpenGl.glCheckFramebufferStatus(GL_FRAMEBUFFER);
  if (frameBufferCheck != GL_FRAMEBUFFER_COMPLETE) {
    angleConsole.error("Framebuffer (depth) check failed: $frameBufferCheck");
  }

  _activeFramebuffer = fbo.value;

  calloc.free(depthBuffer);
  calloc.free(fbo);

  if (!options.customRenderer) {
    _worker = RenderWorker(newTexture);
  }

  return newTexture;
}