Native侧使用OH_NativeImage绘制图片,无任何响应,也不报错

Native侧使用OH_NativeImage绘制图片,无任何响应,也不报错

void MapView::refreshMapView()
{
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "MapView", "refreshMapView execute");
    while (isRefreshMapViewing) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    isRefreshMapViewing = true;
    //////////////////////////////
    // Create context.
    EGLContext m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, CONTEXT_ATTRIBS);
    if (m_eglContext == EGL_NO_CONTEXT) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "Failed to create egl context %x, error:%x", eglGetError());
        return;
    }
    if ((m_eglDisplay == nullptr) || (m_eglSurface == nullptr) || (m_eglContext == nullptr) ||
        (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "refreshMapView eglMakeCurrent failed:%x", eglGetError());
        return;
    }

    glViewport(DEFAULT_X_POSITION, DEFAULT_Y_POSITION, m_width, m_height);
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    // 创建 OpenGL 纹理
    GLuint textureId;
    glGenTextures(1, &textureId);
    // 创建 NativeImage 实例,关联 OpenGL 纹理
    OH_NativeImage *nativeImage = OH_NativeImage_Create(textureId, GL_TEXTURE_EXTERNAL_OES);
    OH_NativeImage_AttachContext(nativeImage, textureId);
    // 获取生产者NativeWindow
    OHNativeWindow *nativeWindow = OH_NativeImage_AcquireNativeWindow(nativeImage);
    int code = SET_BUFFER_GEOMETRY;
    int32_t width = 800;
    int32_t height = 600;
    int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
    if (ret != 0) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "OH_NativeWindow_NativeWindowHandleOpt failed: %d", ret);
    }
    // 从NativeWindow中获取NativeWindowBuffer
    OHNativeWindowBuffer *buffer = nullptr;
    int fenceFd;
    // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
    ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);
    if (ret != 0) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "OH_NativeWindow_NativeWindowRequestBuffer failed: %d", ret);
    }
    BufferHandle *handle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
    // 将生产的内容写入NativeWindowBuffer
    void *mappedAddr = mmap(handle->virAddr, handle->size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0);
    if (mappedAddr == MAP_FAILED) {
        // mmap failed
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "mmap failed");
    }
    static uint32_t value = 0x00;
    value++;
    uint32_t *pixel = static_cast<uint32_t *>(mappedAddr);
    for (uint32_t x = 0; x < width; x++) {
        for (uint32_t y = 0; y < height; y++) {
            *pixel++ = value;
        }
    }
    // 将NativeWindowBuffer提交到NativeWindow
    // 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为NativeWindowBuffer全部有内容更改。
    Region region{nullptr, 0};
    // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
    ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region);
    if (ret != 0) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "OH_NativeWindow_NativeWindowFlushBuffer failed: %d", ret);
    }
    // 内存使用完记得去掉内存映射
    int result = munmap(mappedAddr, handle->size);
    if (result == -1) {
        // munmap failed
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "munmap failed");
    }

    glFlush();
    glFinish();
    if (!eglSwapBuffers(m_eglDisplay, m_eglSurface)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "refreshMapView eglSwapBuffers failed");
    }
    OH_NativeWindow_DestroyNativeWindowBuffer(buffer);
    OH_NativeWindow_DestroyNativeWindow(nativeWindow);
    OH_NativeImage_DetachContext(nativeImage);

    eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglDestroyContext(m_eglDisplay, m_eglContext);

    //////////////////////////////
    isRefreshMapViewing = false;
}

bool MapView::CreateEnvironment()
{
    OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "MapView", "CreateEnvironment execute");
    m_eglWindow = static_cast<EGLNativeWindowType>(m_window);
    if (m_eglWindow == nullptr) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "eglWindow_ is null");
        return false;
    }
    // Init display.
    m_eglDisplay = GetPlatformEglDisplay(EGL_PLATFORM_OHOS_KHR, EGL_DEFAULT_DISPLAY, NULL);
    if (m_eglDisplay == EGL_NO_DISPLAY) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "eglGetDisplay: Failed to create EGLDisplay gl errno : %x", eglGetError());
        return false;
    }

    EGLint majorVersion;
    EGLint minorVersion;
    if (eglInitialize(m_eglDisplay, &majorVersion, &minorVersion) == EGL_FALSE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "eglInitialize: Failed to initialize EGLDisplay");
        return false;
    }

    // 绑定图形绘制的API为OpenGLES
    if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "eglBindAPI: Failed to bind OpenGL ES API");
        return false;
    }

    // Select configuration.
    EGLint numConfigs;
    unsigned int ret = eglChooseConfig(m_eglDisplay, ATTRIB_LIST, &m_eglConfig, 1, &numConfigs);
    if (!(ret && static_cast<unsigned int>(numConfigs) >= 1)) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "eglChooseConfig: Failed to eglChooseConfig");
        return false;
    }
    // Create surface.
    m_eglSurface = eglCreateWindowSurface(m_eglDisplay, m_eglConfig, m_eglWindow, NULL);
    if (m_eglSurface == EGL_NO_SURFACE) {
        OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "MapView", "eglCreateWindowSurface: unable to create surface, error:%x", eglGetError());
        return false;
    }

    return true;
}

2 回复

不应该吧,无任何响应,也不报错,确定代码有执行吗,日志是不是加了搜索或筛选?


在使用OH_NativeImage绘制图片时,如果无任何响应且不报错,可能的原因包括以下几点:

  1. 资源未正确加载:检查图片资源路径是否正确,确保资源文件存在于指定路径,并且资源文件格式符合要求。

  2. NativeImage配置问题:确认OH_NativeImage的配置参数是否正确,包括宽度、高度、颜色格式等。错误的配置可能导致绘制失败。

  3. 绘制时机问题:确保在正确的时机调用绘制函数。例如,在UI线程中调用绘制函数,确保绘制操作在合适的生命周期内执行。

  4. 硬件加速问题:某些设备可能不支持特定的硬件加速功能,导致绘制无响应。可以尝试禁用硬件加速,查看是否有效果。

  5. 内存问题:检查内存使用情况,确保没有内存泄漏或内存不足的情况。内存问题可能导致绘制操作无法正常执行。

  6. 日志输出问题:虽然不报错,但可以尝试增加日志输出,检查绘制函数的执行情况,确认是否进入了绘制函数。

  7. 系统兼容性问题:不同版本的系统可能存在兼容性问题,确保代码在目标系统版本上进行了充分测试。

通过排查以上可能的原因,可以逐步定位问题所在。

回到顶部