Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
18ff8485
D
Docs
项目概览
OpenHarmony
/
Docs
大约 2 年 前同步成功
通知
161
Star
293
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
18ff8485
编写于
7月 21, 2023
作者:
O
openharmony_ci
提交者:
Gitee
7月 21, 2023
浏览文件
操作
浏览文件
下载
差异文件
!21051 【3.2Release】修复资料代码的准确性
Merge pull request !21051 from shegangbin/fix_native_window_md_3.2_release
上级
15f2b8b0
46e122a2
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
111 addition
and
104 deletion
+111
-104
zh-cn/application-dev/napi/native-window-guidelines.md
zh-cn/application-dev/napi/native-window-guidelines.md
+111
-104
未找到文件。
zh-cn/application-dev/napi/native-window-guidelines.md
浏览文件 @
18ff8485
# NativeWindow
开发指导
# NativeWindow开发指导
## 场景介绍
## 场景介绍
NativeWindow是
`OpenHarmony`
**本地平台化窗口**
,表示图形队列的生产者端。
接口能力包括从
`Surface`
构建
`NativeWindow`
的能力,从
`SurfaceBuffer`
构建出
`NativeWindowBuffer`
的能力,开发者可以通过
`NativeWindow`
接口进行申请和提交
`Buffer`
。
NativeWindow是
`OpenHarmony`
**本地平台化窗口**
,表示图形队列的生产者端。
开发者可以通过
`NativeWindow`
接口进行申请和提交
`Buffer`
,配置
`Buffer`
属性信息
。
针对NativeWindow,常见的开发场景如下:
针对NativeWindow,常见的开发场景如下:
*
通过
`NativeWindow`
提供的
`NAPI`
接口申请图形
`Buffer`
,并将生产图形内容写入图形
`Buffer`
,最终提交
`Buffer`
到图形队列
*
通过
`NativeWindow`
提供的
Native API
接口申请图形
`Buffer`
,并将生产图形内容写入图形
`Buffer`
,最终提交
`Buffer`
到图形队列
*
在适配EGL层的
`eglswapbuffer`
接口时,进行申请和提交
`Buffer`
*
在适配EGL层的
`eglswapbuffer`
接口时,进行申请和提交
`Buffer`
## 接口说明
## 接口说明
| 接口名 | 描述 |
| 接口名 | 描述 |
| -------- | -------- |
| -------- | -------- |
| OH_NativeWindow_CreateNativeWindowFromSurface (void
\*
pSurface) | 创建NativeWindow实例,每次调用都会产生一个新的NativeWindow实例。 |
| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow
\*
window, OHNativeWindowBuffer
\*\*
buffer, int
\*
fenceFd) | 通过OHNativeWindow对象申请一块OHNativeWindowBuffer,用以内容生产。 |
| OH_NativeWindow_DestroyNativeWindow (OHNativeWindow
\*
window) | 将NativeWindow对象的引用计数减1,当引用计数为0的时候,该NativeWindow对象会被析构掉。 |
| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow
\*
window, OHNativeWindowBuffer
\*
buffer, int fenceFd, Region region) | 通过OHNativeWindow将生产好内容的OHNativeWindowBuffer放回到Buffer队列中,用以内容消费。 |
| OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void
\*
pSurfaceBuffer) | 创建NativeWindowBuffer实例,每次调用都会产生一个新的NativeWindowBuffer实例。 |
| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow
\*
window, int code,...) | 设置/获取OHNativeWindow的属性,包括设置/获取宽高、内容格式等。 |
| OH_NativeWindow_DestroyNativeWindowBuffer (OHNativeWindowBuffer
\*
buffer) | 将NativeWindowBuffer对象的引用计数减1,当引用计数为0的时候,该NativeWindowBuffer对象会被析构掉。 |
| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow
\*
window, OHNativeWindowBuffer
\*\*
buffer, int
\*
fenceFd) | 通过NativeWindow对象申请一块NativeWindowBuffer,用以内容生产。 |
| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow
\*
window, OHNativeWindowBuffer
\*
buffer, int fenceFd, Region region) | 通过NativeWindow将生产好内容的NativeWindowBuffer放回到Buffer队列中,用以内容消费。 |
| OH_NativeWindow_NativeWindowAbortBuffer (OHNativeWindow
\*
window, OHNativeWindowBuffer
\*
buffer) | 通过NativeWindow将之前申请出来的NativeWindowBuffer返还到Buffer队列中,供下次再申请。 |
| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow
\*
window, int code,...) | 设置/获取NativeWindow的属性,包括设置/获取宽高、内容格式等。 |
| OH_NativeWindow_GetBufferHandleFromNative (OHNativeWindowBuffer
\*
buffer) | 通过NativeWindowBuffer获取该buffer的BufferHandle指针。 |
| OH_NativeWindow_NativeObjectReference (void
\*
obj) | 增加一个NativeObject的引用计数。 |
| OH_NativeWindow_NativeObjectUnreference (void
\*
obj) | 减少一个NativeObject的引用计数,当引用计数减少为0时,该NativeObject将被析构掉。 |
| OH_NativeWindow_GetNativeObjectMagic (void
\*
obj) | 获取NativeObject的MagicId。 |
| OH_NativeWindow_NativeWindowSetScalingMode (OHNativeWindow
\*
window, uint32_t sequence, OHScalingMode scalingMode) | 设置NativeWindow的缩放模式。 |
| OH_NativeWindow_NativeWindowSetMetaData(OHNativeWindow
\*
window, uint32_t sequence, int32_t size, const OHHDRMetaData
\*
metaData) | 设置NativeWindow的HDR静态元数据。 |
| OH_NativeWindow_NativeWindowSetMetaDataSet(OHNativeWindow
\*
window, uint32_t sequence, OHHDRMetadataKey key, int32_t size, const uint8_t
\*
metaData) | 设置NativeWindow的HDR静态元数据集。 |
| OH_NativeWindow_NativeWindowSetTunnelHandle(OHNativeWindow
\*
window, const OHExtDataHandle
\*
handle) | 设置NativeWindow的TunnelHandle。 |
详细的接口说明请参考
[
native_window
](
../reference/native-apis/_native_window.md
)
。
详细的接口说明请参考
[
native_window
](
../reference/native-apis/_native_window.md
)
。
## 开发步骤
## 开发步骤
以下步骤描述了在
**OpenHarmony**
中如何使用
`NativeWindow`
提供的
`NAPI`
接口,申请图形
`Buffer`
,并将生产图形内容写入图形
`Buffer`
后,最终提交
`Buffer`
到图形队列。
以下步骤描述了在
**OpenHarmony**
中如何使用
`NativeWindow`
提供的
Native API
接口,申请图形
`Buffer`
,并将生产图形内容写入图形
`Buffer`
后,最终提交
`Buffer`
到图形队列。
1.
**获取NativeWindow实例**
。可在
[
`OH_NativeXComponent_Callback`
](
../reference/native-apis/_o_h___native_x_component___callback.md
)
提供的接口中获取。
**添加动态链接库**
1.
在xxx.ets 中定义 XComponent。
CMakeLists.txt中添加以下lib。
```
txt
libace_ndk.z.so
libnative_window.so
```
**头文件**
```
c++
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <native_window/external_window.h>
```
1.
**获取OHNativeWindow实例**
。
可在[`OH_NativeXComponent_Callback`](../reference/native-apis/_o_h___native_x_component___callback.md)提供的接口中获取OHNativeWindow,下面提供一份代码示例。XComponent模块的具体使用方法请参考[XComponent](../ui/arkts-common-components-xcomponent.md)。
1. 在xxx.ets中添加一个XComponent组件。
```ts
```ts
XComponent
({
id
:
'
xcomponentId
'
,
type
:
'
surface
'
,
libraryname
:
'
nativerender
'
})
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'entry'})
.
onLoad
((
context
)
=>
{
.width(360)
this
.
context
=
context
;
.height(360)
})
.
onDestroy
(()
=>
{
})
```
```
2. 在 native c++ 层获取 NativeXComponent。
2. 在 native c++ 层获取 NativeXComponent。
```c++
```c++
napi_value exportInstance = nullptr;
napi_value exportInstance = nullptr;
// 用来解析出被wrap了NativeXComponent指针的属性
napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
OH_NativeXComponent *nativeXComponent = nullptr;
OH_NativeXComponent *nativeXComponent = nullptr;
// 通过napi_unwrap接口,解析出NativeXComponent的实例指针
napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
char
idStr
[
OH_XCOMPONENT_ID_LEN_MAX
+
1
]
=
{
};
uint64_t
idSize
=
OH_XCOMPONENT_ID_LEN_MAX
+
1
;
OH_NativeXComponent_GetXComponentId
(
nativeXComponent
,
idStr
,
&
idSize
);
```
```
3. 定义 OH_NativeXComponent_Callback。
3. 定义 OH_NativeXComponent_Callback。
```c++
```c++
// 定义回调函数
// 定义回调函数
void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
{
{
// 可获取
NativeWindow 实例
// 可获取 OH
NativeWindow 实例
OHNativeWindow
*
nativeWindow = window
;
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window)
;
// ...
// ...
}
}
void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
{
{
// 可获取
NativeWindow 实例
// 可获取 OH
NativeWindow 实例
OHNativeWindow
*
nativeWindow = window
;
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window)
;
// ...
// ...
}
}
void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
{
{
// 可获取
NativeWindow 实例
// 可获取 OH
NativeWindow 实例
OHNativeWindow
*
nativeWindow = window
;
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window)
;
// ...
// ...
}
}
void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
{
{
// 可获取
NativeWindow 实例
// 可获取 OH
NativeWindow 实例
OHNativeWindow
*
nativeWindow = window
;
OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window)
;
// ...
// ...
}
}
```
```
```c++
```c++
// 初始化 OH_NativeXComponent_Callback
// 初始化 OH_NativeXComponent_Callback
OH_NativeXComponent_Callback callback_
;
OH_NativeXComponent_Callback callback
;
callback_->
OnSurfaceCreated = OnSurfaceCreatedCB;
callback.
OnSurfaceCreated = OnSurfaceCreatedCB;
callback_->
OnSurfaceChanged = OnSurfaceChangedCB;
callback.
OnSurfaceChanged = OnSurfaceChangedCB;
callback_->
OnSurfaceDestroyed = OnSurfaceDestroyedCB;
callback.
OnSurfaceDestroyed = OnSurfaceDestroyedCB;
callback_->
DispatchTouchEvent = DispatchTouchEventCB;
callback.
DispatchTouchEvent = DispatchTouchEventCB;
```
```
4.
将 OH_NativeXComponent_Callback 注册给 NativeXComponent。
4.
将 OH_NativeXComponent_Callback 注册给 NativeXComponent。
```
c++
```
c++
OH_NativeXComponent_RegisterCallback
(
nativeXComponent
,
&
callback_
);
// 注册回调函数
OH_NativeXComponent_RegisterCallback
(
nativeXComponent
,
&
callback
);
```
```
2.
**设置
NativeWindowBuffer的属性**
。使用
`OH_NativeWindow_NativeWindowHandleOpt`
设置
`
NativeWindowBuffer`
的属性。
2.
**设置
OHNativeWindowBuffer的属性**
。使用
`OH_NativeWindow_NativeWindowHandleOpt`
设置
`OH
NativeWindowBuffer`
的属性。
```
c++
```
c++
// 设置 NativeWindowBuffer 的读写场景
// 设置 OHNativeWindowBuffer 的宽高
int
code
=
SET_USAGE
;
int32_t
code
=
SET_BUFFER_GEOMETRY
;
int32_t
usage
=
BUFFER_USAGE_CPU_READ
|
BUFFER_USAGE_CPU_WRITE
|
BUFFER_USAGE_MEM_DMA
;
int32_t
ret
=
OH_NativeWindow_NativeWindowHandleOpt
(
nativeWindow
,
code
,
usage
);
// 设置 NativeWindowBuffer 的宽高
code
=
SET_BUFFER_GEOMETRY
;
int32_t
width
=
0x100
;
int32_t
width
=
0x100
;
int32_t
height
=
0x100
;
int32_t
height
=
0x100
;
ret
=
OH_NativeWindow_NativeWindowHandleOpt
(
nativeWindow
,
code
,
width
,
height
);
// 这里的nativeWindow是从上一步骤中的回调函数中获得的
// 设置 NativeWindowBuffer 的步长
int32_t
ret
=
OH_NativeWindow_NativeWindowHandleOpt
(
nativeWindow
,
code
,
width
,
height
);
// 设置 OHNativeWindowBuffer 的步长
code
=
SET_STRIDE
;
code
=
SET_STRIDE
;
int32_t
stride
=
0x8
;
int32_t
stride
=
0x8
;
ret
=
OH_NativeWindow_NativeWindowHandleOpt
(
nativeWindow
,
code
,
stride
);
ret
=
OH_NativeWindow_NativeWindowHandleOpt
(
nativeWindow
,
code
,
stride
);
// 设置 NativeWindowBuffer 的格式
code
=
SET_FORMAT
;
int32_t
format
=
PIXEL_FMT_RGBA_8888
;
ret
=
OH_NativeWindow_NativeWindowHandleOpt
(
nativeWindow
,
code
,
format
);
```
```
3.
**从图形队列申请NativeWindowBuffer**
。
3.
**从图形队列申请
OH
NativeWindowBuffer**
。
```
c++
```
c++
struct
NativeWindowBuffer
*
buffer
=
nullptr
;
OH
NativeWindowBuffer
*
buffer
=
nullptr
;
int
fenceFd
;
int
fenceFd
;
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 NativeWindowBuffer 实例
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
OH_NativeWindow_NativeWindowRequestBuffer
(
nativeWindow_
,
&
buffer
,
&
fenceFd
);
OH_NativeWindow_NativeWindowRequestBuffer
(
nativeWindow
,
&
buffer
,
&
fenceFd
);
// 通过 OH_NativeWindow_GetNativeBufferHandleFromNative 获取 buffer 的 handle
// 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle
BufferHandle
*
bufferHandle
=
OH_NativeWindow_GetNativeBufferHandleFromNative
(
buffer
);
BufferHandle
*
bufferHandle
=
OH_NativeWindow_GetBufferHandleFromNative
(
buffer
);
```
4.
**内存映射mmap**
。
```
c++
#include <sys/mman.h>
// 使用系统mmap接口拿到bufferHandle的内存虚拟地址
void
*
mappedAddr
=
mmap
(
bufferHandle
->
virAddr
,
bufferHandle
->
size
,
PROT_READ
|
PROT_WRITE
,
MAP_SHARED
,
bufferHandle
->
fd
,
0
);
if
(
mappedAddr
==
MAP_FAILED
)
{
// mmap failed
}
```
```
4.
**将生产的内容写入
NativeWindowBuffer**
。
5.
**将生产的内容写入OH
NativeWindowBuffer**
。
```
c++
```
c++
auto
image
=
static_cast
<
uint8_t
*>
(
buffer
->
sfbuffer
->
GetVirAddr
());
static
uint32_t
value
=
0x00
;
static
uint32_t
value
=
0x00
;
value
++
;
value
++
;
uint32_t
*
pixel
=
static_cast
<
uint32_t
*>
(
mappedAddr
);
// 使用mmap获取到的地址来访问内存
uint32_t
*
pixel
=
static_cast
<
uint32_t
*>
(
image
);
for
(
uint32_t
x
=
0
;
x
<
width
;
x
++
)
{
for
(
uint32_t
x
=
0
;
x
<
width
;
x
++
)
{
for
(
uint32_t
y
=
0
;
y
<
height
;
y
++
)
{
for
(
uint32_t
y
=
0
;
y
<
height
;
y
++
)
{
*
pixel
++
=
value
;
*
pixel
++
=
value
;
...
@@ -143,10 +142,18 @@ NativeWindow是`OpenHarmony`**本地平台化窗口**,表示图形队列的生
...
@@ -143,10 +142,18 @@ NativeWindow是`OpenHarmony`**本地平台化窗口**,表示图形队列的生
}
}
```
```
5.
**提交NativeWindowBuffer到图形队列**
。
5.
**提交
OH
NativeWindowBuffer到图形队列**
。
```
c++
```
c++
// 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为NativeWindowBuffer全部有内容更改。
// 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为
OH
NativeWindowBuffer全部有内容更改。
Region
region
{
nullptr
,
0
};
Region
region
{
nullptr
,
0
};
// 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
// 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
OH_NativeWindow_NativeWindowFlushBuffer
(
nativeWindow_
,
buffer
,
fenceFd
,
region
);
OH_NativeWindow_NativeWindowFlushBuffer
(
nativeWindow
,
buffer
,
fenceFd
,
region
);
```
6.
**取消内存映射munmap**
。
```
c++
// 内存使用完记得去掉内存映射
int
result
=
munmap
(
mappedAddr
,
bufferHandle
->
size
);
if
(
result
==
-
1
)
{
// munmap failed
}
```
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录