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绘制图片时,如果无任何响应且不报错,可能的原因包括以下几点:
-
资源未正确加载:检查图片资源路径是否正确,确保资源文件存在于指定路径,并且资源文件格式符合要求。
-
NativeImage配置问题:确认OH_NativeImage的配置参数是否正确,包括宽度、高度、颜色格式等。错误的配置可能导致绘制失败。
-
绘制时机问题:确保在正确的时机调用绘制函数。例如,在UI线程中调用绘制函数,确保绘制操作在合适的生命周期内执行。
-
硬件加速问题:某些设备可能不支持特定的硬件加速功能,导致绘制无响应。可以尝试禁用硬件加速,查看是否有效果。
-
内存问题:检查内存使用情况,确保没有内存泄漏或内存不足的情况。内存问题可能导致绘制操作无法正常执行。
-
日志输出问题:虽然不报错,但可以尝试增加日志输出,检查绘制函数的执行情况,确认是否进入了绘制函数。
-
系统兼容性问题:不同版本的系统可能存在兼容性问题,确保代码在目标系统版本上进行了充分测试。
通过排查以上可能的原因,可以逐步定位问题所在。