ITPub博客

首页 > 应用开发 > IT综合 > HarmonyOS:NativeWindow 开发指导

HarmonyOS:NativeWindow 开发指导

IT综合 作者:HarmonyOS开发者社区 时间:2023-12-12 15:17:14 0 删除 编辑

场景介绍

NativeWindow 是 HarmonyOS 本地平台化窗口,表示图形队列的生产者端。开发者可以通过 NativeWindow 接口进行申请和提交 Buffer,配置 Buffer 属性信息。

针对 NativeWindow,常见的开发场景如下:

●  通过 NativeWindow 提供的 Native API 接口申请图形 Buffer,并将生产图形内容写入图形 Buffer,最终提交 Buffer 到图形队列

●  在适配 EGL 层的 eglswapbuffer 接口时,进行申请和提交 Buffer

接口说明


详细的接口说明请参考 native_window 。

开发步骤

以下步骤描述了在 HarmonyOS 中如何使用 NativeWindow 提供的 Native API 接口,申请图形 Buffer,并将生产图形内容写入图形 Buffer 后,最终提交 Buffer 到图形队列。

添加动态链接库

CMakeLists.txt 中添加以下 lib。


libace_ndk.z.so
libnative_window.so




头文件



#
include 
<ace/xcomponent/native_interface_xcomponent.h>

#
include 
<native_window/external_window.h>


复制代码


1.  获取 OHNativeWindow 实例。

可在 OH_NativeXComponent_Callback 提供的接口中获取 OHNativeWindow,下面提供一份代码示例。XComponent 模块的具体使用方法请参考 XComponent开发指导 。

a.  在 xxx.ets 中添加一个 XComponent 组件。


XComponent({ 
id: 
'xcomponentId', 
type: 
'surface', libraryname: 
'entry'})
    .width(
360)
    .height(
360)




b.  在 native c++ 层获取 NativeXComponent。



napi_value 
exportInstance 
= nullptr;

// 用来解析出被wrap了NativeXComponent指针的属性
napi_get_named_property(env, 
exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
OH_NativeXComponent *nativeXComponent = nullptr;

// 通过napi_unwrap接口,解析出NativeXComponent的实例指针
napi_unwrap(env, exportInstance, reinterpret_cast<
void**>(&nativeXComponent));

// 获取XComponentId

char idStr[OH_XCOMPONENT_ID_LEN_MAX + 
1] = {};

uint64_t 
idSize 
= OH_XCOMPONENT_ID_LEN_MAX + 
1;
OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);




c.  定义 OH_NativeXComponent_Callback。



// 定义回调函数

void 
OnSurfaceCreatedCB(OH_NativeXComponent* component, 
void* 
window)
{
    
// 可获取 OHNativeWindow 实例
    
OHNativeWindow* nativeWindow = static_cast<
OHNativeWindow*>(
window);
    
// ...
}

void 
OnSurfaceChangedCB(OH_NativeXComponent* component, 
void* 
window)
{
    
// 可获取 OHNativeWindow 实例
    
OHNativeWindow* nativeWindow = static_cast<
OHNativeWindow*>(
window);
    
// ...
}

void 
OnSurfaceDestroyedCB(OH_NativeXComponent* component, 
void* 
window)
{
    
// 可获取 OHNativeWindow 实例
    
OHNativeWindow* nativeWindow = static_cast<
OHNativeWindow*>(
window);
    
// ...
}

void 
DispatchTouchEventCB(OH_NativeXComponent* component, 
void* 
window)
{
    
// 可获取 OHNativeWindow 实例
    
OHNativeWindow* nativeWindow = static_cast<
OHNativeWindow*>(
window);
    
// ...
}






// 初始化 OH_NativeXComponent_Callback
OH_NativeXComponent_Callback callback;
callback.
OnSurfaceCreated = 
OnSurfaceCreatedCB;
callback.
OnSurfaceChanged = 
OnSurfaceChangedCB;
callback.
OnSurfaceDestroyed = 
OnSurfaceDestroyedCB;
callback.
DispatchTouchEvent = 
DispatchTouchEventCB;




d.  将 OH_NativeXComponent_Callback 注册给 NativeXComponent。



// 注册回调函数

OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);




2.  设置 OHNativeWindowBuffer 的属性。使用 OH_NativeWindow_NativeWindowHandleOpt 设置 OHNativeWindowBuffer 的属性。



// 设置 OHNativeWindowBuffer 的宽高

int32_t 
code 
= SET_BUFFER_GEOMETRY;

int32_t 
width 
= 
0x100;

int32_t 
height 
= 
0x100;

// 这里的nativeWindow是从上一步骤中的回调函数中获得的

int32_t 
ret 
= OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);




3.  从图形队列申请 OHNativeWindowBuffer。


OHNativeWindowBuffer* buffer = 
nullptr;

int fenceFd;

// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例

OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);

// 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle
BufferHandle* bufferHandle = 
OH_NativeWindow_GetBufferHandleFromNative(buffer);




4.  内存映射 mmap。



#include <sys/mman.h>


// 使用系统接口mmap将bufferHandle对应的共享内存映射到用户空间,可以通过映射出来的虚拟地址向bufferHandle中写入图像数据 // bufferHandle->virAddr是bufferHandle在共享内存中的起始地址,bufferHandle->size是bufferHandle在共享内存中的内存占用大小 void* mappedAddr = mmap(bufferHandle->virAddr, bufferHandle->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle->fd, 0); if (mappedAddr == MAP_FAILED) {     // mmap failed }



5.  将生产的内容写入 OHNativeWindowBuffer。



static 
uint32_t value = 
0x00;
value++;

uint32_t *pixel = 
static_cast<
uint32_t *>(mappedAddr); 
// 使用mmap获取到的地址来访问内存

for (
uint32_t x = 
0; x < width; x++) {
    
for (
uint32_t y = 
0;  y < height; y++) {
        *pixel++ = value;
    }
}




6.  提交 OHNativeWindowBuffer 到图形队列。



// 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。
Region region{
nullptr, 
0};

// 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。

OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region);




7.  取消内存映射 munmap。



// 内存使用完记得去掉内存映射

int result = munmap(mappedAddr, bufferHandle->size);

if (result == -
1) {
    
// munmap failed
}



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70047792/viewspace-2999776/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2021-11-18

  • 博文量
    401
  • 访问量
    296730