HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题

HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题 关于这个问题,我提问过:链接,但是问题还没解决。我在描述一下问题,如何在Flutter中使用OpenGL,我参考了在Flutter Android中使用外接纹理的方法,类似的代码在 OHOS 中并不工作。我发现 Flutter Android 中的

TextureRegistry、SurfaceTexture,在 OHOS中都有类的定义,

在上述 Java 代码中,glRender 核心实现是在 C++中完成的,关键代码是将 surfaceTexture 传入glRender 中,这个 surfaceTexture 在初始化OpenGL 的 eglCreateWindowSurface 函数中作为第三个参数,这个代码在 Android flutter 中是有效的,但是同样的代码在 OHOS 中不能工作,下面是 ArkTS 的代码:

onAttachedToEngine(binding: FlutterPluginBinding): void {
    Log.e("EmuGLRenderPlugin", "EmuGLRenderPlugin onAttachedToEngine");
    this.channel = new MethodChannel(binding.getBinaryMessenger(), "gl_render");
    this.channel.setMethodCallHandler(this)
    this.textureRegistry = binding.getTextureRegistry();
    this.surfaceTexture = this.textureRegistry.createSurfaceTexture();
}

onMethodCall(call: MethodCall, result: MethodResult): void {
    if (call.method == "makeFlutterTextureId") {
        let surfaceId: number = this.surfaceTexture!.getSurfaceId()
        let dataPtr: number = call.argument("share_data")
        result.success(native.makeGL(surfaceId, dataPtr))
    } else {
        result.notImplemented()
    }
}

在调用 native.makeGL(surfaceId, dataPtr) 的时候,主要是在创建 windows surface 的时候出错:0x300B EGL_BAD_NATIVE_WINDOW,C++ 部分的代码如下:

static int64_t initGL(int64_t surfaceId, int64_t dataPtr) {
    s_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if (s_eglDisplay == EGL_NO_DISPLAY) {
        return -1;
    }

    EGLint version[2];
    if (!eglInitialize(s_eglDisplay, &version[0], &version[1])) {
        return -2;
    }

    EGLConfig eglConfig;
    int64_t v = chooseEglConfig(eglConfig);
    if (v != 1) {
        return -3;
    }

    EGLint attribList[] = {
        EGL_CONTEXT_CLIENT_VERSION, 3,
        EGL_NONE
    };

    s_eglContext = eglCreateContext(s_eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList);
    if (s_eglContext == EGL_NO_CONTEXT) {
        EGLint error = eglGetError();
        OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "GL_NATIVE", "Failed to create EGL context: %x", error);
        return -4;
    }

    s_eglSurface = eglCreateWindowSurface(s_eglDisplay, eglConfig, (EGLNativeWindowType)surfaceId, nullptr);
    if (s_eglSurface == EGL_NO_SURFACE) {
        EGLint error = eglGetError();
        OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "GL_NATIVE", "Failed to create window surface: %x", error);
        return error;
    }

    return 0;
}

static int64_t chooseEglConfig(EGLConfig &config) {
    EGLint configsCount;
    EGLint configSpec[] = {
        EGL_RENDERABLE_TYPE, 64,
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_DEPTH_SIZE, 16,
        EGL_STENCIL_SIZE, 0,
        EGL_SAMPLE_BUFFERS, 1,
        EGL_SAMPLES, 4,
        EGL_NONE
    };

    if (!eglChooseConfig(s_eglDisplay, configSpec, &config, 1, &configsCount)) {
        EGLint error = eglGetError();
        OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "GL_NATIVE", "Failed to choose config: %x", error);
        return error;
    } else if (configsCount > 0) {
        return 1;
    }
    return 0;
}

错误就发生在 eglCreateWindowSurfaceeglGetError 返回 EGL_BAD_NATIVE_WINDOW,查看flutter 的 TextureRegistry,这个surface 来自于 PixelMap,但是用 eglCreatePixmapSurface 替换 eglCreateWindowSurface 又报错 0x3009 EGL_BAD_MATCH,但是上述代码在 Android 中是没有问题的,在 OHOS中创建这个 Surface 要如何做?


更多关于HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题的实战教程也可以访问 https://www.itying.com/category-92-b0.html

4 回复

onAttachedToEngine(binding: FlutterPluginBinding): void { this.textureRegistry = binding.getTextureRegistry(); this.surfaceTexture = this.textureRegistry.registerTexture(this.textureRegistry.getTextureId(); // 得到 surfaceId let surfaceId: number = this.surfaceTexture.getSurfaceId(); }

// 然后在c++层通过surfaceId创建nativeWindow,之后就可以用opengl了 OHNativeWindow *nativeWindow = nullptr; OH_NativeWindow_CreateNativeWindowFromSurfaceId(surface_id, &nativeWindow); OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, 360, 480);

更多关于HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


感谢回答,最近没注意看论坛,刚看到你的回答,按照你说的,我修改了相关代码,现在GL 能够初始化成功了,但是在每一帧渲染完成,我调用 eglSwapBuffers 的时候报错:EGL_BAD_ALLOC,类似的代码,在 android 上是OK的, flutter 使用 opengl 外接纹理和 android 是很类似的,ohos 的代码,基本上也是android 上的复制版。在看到你的回答之前,我已经通过 XComponent + PlatformView 的方式基本上解决了这个问题,在iOS 和 android 上正常使用 flutter 的外接 opengl 纹理,在 ohos 上封装一个XComponent的PlatformView,也能实现 opengl 的渲染。不过我还是希望能够和 iOS 与 android 保持一致,使用通用的代码,不知能够提供一个在ohos 上 flutter 使用 opengl 外接纹理的例子。

针对帖子标题“HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题”,以下是专业且简洁的回答:

在HarmonyOS鸿蒙系统中,当使用Flutter框架并希望通过外接纹理(External Texture)集成OpenGL时,需确保几个关键点:

  1. 纹理创建与绑定:首先,在OpenGL中创建纹理对象,并绑定到当前渲染上下文。这通常涉及生成纹理ID、分配纹理内存以及设置纹理参数。

  2. Flutter平台通道:利用Flutter的平台通道(Platform Channel)机制,将OpenGL纹理ID或其他必要信息传递给Flutter层。这允许Flutter应用与原生代码进行通信。

  3. 纹理更新与渲染:在Flutter中,使用Texture widget来显示来自OpenGL的纹理。确保在OpenGL中正确更新纹理内容,并通知Flutter层进行渲染。

  4. 同步与性能:注意OpenGL与Flutter渲染管道之间的同步问题,以避免潜在的渲染错误或性能瓶颈。

  5. 错误处理:检查OpenGL错误码和Flutter日志,以快速定位并解决问题。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。这将提供进一步的帮助和支持。

回到顶部