Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
b568682d
D
Docs
项目概览
OpenHarmony
/
Docs
大约 1 年 前同步成功
通知
159
Star
292
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看板
未验证
提交
b568682d
编写于
10月 21, 2022
作者:
O
openharmony_ci
提交者:
Gitee
10月 21, 2022
浏览文件
操作
浏览文件
下载
差异文件
!10903 更新NativeWindow NAPI 使用指导
Merge pull request !10903 from Andrew0229/cherry-pick-1666316104
上级
edcdf73d
0acb3957
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
67 addition
and
74 deletion
+67
-74
zh-cn/application-dev/napi/native-window-guidelines.md
zh-cn/application-dev/napi/native-window-guidelines.md
+67
-74
未找到文件。
zh-cn/application-dev/napi/native-window-guidelines.md
浏览文件 @
b568682d
...
...
@@ -2,112 +2,105 @@
## 场景介绍
NativeWindow是
`OpenHarmony`
**本地平台化窗口**
,
包括从
`Surface`
构建
`NativeWindow`
,从
`SurfaceBuffer`
构建出
`NativeWindowBuffer`
的能力,开发者可以通过
`NativeWindow`
接口进行申请和提交
`Buffer`
。
NativeWindow是
`OpenHarmony`
**本地平台化窗口**
,
表示图形队列的生产者端。接口能力包括从
`Surface`
构建
`NativeWindow`
的能力
,从
`SurfaceBuffer`
构建出
`NativeWindowBuffer`
的能力,开发者可以通过
`NativeWindow`
接口进行申请和提交
`Buffer`
。
针对NativeWindow,常见的开发场景如下:
*
通过
`Native
C++`
代码绘制内容并显示在屏幕上
*
在适配EGL层的
`eglswapbuffer`
接口时,进行
提交和申请
`Buffer`
*
通过
`Native
Window`
提供的
`NAPI`
接口申请图形
`Buffer`
,并将生产图形内容写入图形
`Buffer`
,最终提交
`Buffer`
到图形队列
*
在适配EGL层的
`eglswapbuffer`
接口时,进行
申请和提交
`Buffer`
## 接口说明
| 接口名 | 描述 |
| -------- | -------- |
| OH_NativeWindow_CreateNativeWindowFromSurface (void
\*
pSurface) | 创建NativeWindow实例,每次调用都会产生一个新的NativeWindow实例。 |
| OH_NativeWindow_DestroyNativeWindow (
struct
NativeWindow
\*
window) | 将NativeWindow对象的引用计数减1,当引用计数为0的时候,该NativeWindow对象会被析构掉。 |
| OH_NativeWindow_DestroyNativeWindow (
OH
NativeWindow
\*
window) | 将NativeWindow对象的引用计数减1,当引用计数为0的时候,该NativeWindow对象会被析构掉。 |
| OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void
\*
pSurfaceBuffer) | 创建NativeWindowBuffer实例,每次调用都会产生一个新的NativeWindowBuffer实例。 |
| OH_NativeWindow_DestroyNativeWindowBuffer (
struct
NativeWindowBuffer
\*
buffer) | 将NativeWindowBuffer对象的引用计数减1,当引用计数为0的时候,该NativeWindowBuffer对象会被析构掉。 |
| OH_NativeWindow_NativeWindowRequestBuffer (
struct NativeWindow
\*
window struct
NativeWindowBuffer
\*\*
buffer, int
\*
fenceFd) | 通过NativeWindow对象申请一块NativeWindowBuffer,用以内容生产。 |
| OH_NativeWindow_NativeWindowFlushBuffer (
struct NativeWindow
\*
window, struct
NativeWindowBuffer
\*
buffer, int fenceFd, Region region) | 通过NativeWindow将生产好内容的NativeWindowBuffer放回到Buffer队列中,用以内容消费。 |
| OH_NativeWindow_NativeWindow
CancelBuffer (struct NativeWindow
\*
window, struct
NativeWindowBuffer
\*
buffer) | 通过NativeWindow将之前申请出来的NativeWindowBuffer返还到Buffer队列中,供下次再申请。 |
| OH_NativeWindow_NativeWindowHandleOpt (
struct
NativeWindow
\*
window, int code,...) | 设置/获取NativeWindow的属性,包括设置/获取宽高、内容格式等。 |
| OH_NativeWindow_GetBufferHandleFromNative (
struct
NativeWindowBuffer
\*
buffer) | 通过NativeWindowBuffer获取该buffer的BufferHandle指针。 |
| OH_NativeWindow_DestroyNativeWindowBuffer (
OH
NativeWindowBuffer
\*
buffer) | 将NativeWindowBuffer对象的引用计数减1,当引用计数为0的时候,该NativeWindowBuffer对象会被析构掉。 |
| OH_NativeWindow_NativeWindowRequestBuffer (
OHNativeWindow
\*
window, OH
NativeWindowBuffer
\*\*
buffer, int
\*
fenceFd) | 通过NativeWindow对象申请一块NativeWindowBuffer,用以内容生产。 |
| OH_NativeWindow_NativeWindowFlushBuffer (
OHNativeWindow
\*
window, OH
NativeWindowBuffer
\*
buffer, int fenceFd, Region region) | 通过NativeWindow将生产好内容的NativeWindowBuffer放回到Buffer队列中,用以内容消费。 |
| OH_NativeWindow_NativeWindow
AbortBuffer (OHNativeWindow
\*
window, OH
NativeWindowBuffer
\*
buffer) | 通过NativeWindow将之前申请出来的NativeWindowBuffer返还到Buffer队列中,供下次再申请。 |
| OH_NativeWindow_NativeWindowHandleOpt (
OH
NativeWindow
\*
window, int code,...) | 设置/获取NativeWindow的属性,包括设置/获取宽高、内容格式等。 |
| OH_NativeWindow_GetBufferHandleFromNative (
OH
NativeWindowBuffer
\*
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
)
。
## 开发步骤
以下步骤描述了在
**OpenHarmony**
中如何
利用
`OH_NativeXComponent`
通过
`Native C++`
代码绘制内容并显示在屏幕上
。
以下步骤描述了在
**OpenHarmony**
中如何
使用
`NativeWindow`
提供的
`NAPI`
接口,申请图形
`Buffer`
,并将生产图形内容写入图形
`Buffer`
后,最终提交
`Buffer`
到图形队列
。
1.
**在页面中定义XComponent组件**
,在
`index.ets`
中定义一个
`texture`
类型的
`XComponent`
,用于显示内容。
```
js
XComponent
({
id
:
'
xcomponentId
'
,
type
:
'
texture
'
,
libraryname
:
'
nativerender
'
})
.
borderColor
(
Color
.
Red
)
.
borderWidth
(
5
)
.
onLoad
(()
=>
{})
.
onDestroy
(()
=>
{})
```
2.
**获取OH_NativeXComponent实例**
。使用
`napi_get_named_property`
接口获取一个
`OH_NativeXComponent`
实例
`nativeXComponent`
,通过注册该实例的回调接口获取
`NativeWindow`
实例。
1.
**获取NativeWindow实例**
。例如,使用
`Surface`
创建
`NativeWindow`
实例。
```
c++
sptr
<
OHOS
::
Surface
>
cSurface
=
Surface
::
CreateSurfaceAsConsumer
();
sptr
<
IBufferConsumerListener
>
listener
=
new
BufferConsumerListenerTest
();
cSurface
->
RegisterConsumerListener
(
listener
);
sptr
<
OHOS
::
IBufferProducer
>
producer
=
cSurface
->
GetProducer
();
sptr
<
OHOS
::
Surface
>
pSurface
=
Surface
::
CreateSurfaceAsProducer
(
producer
);
OHNativeWindow
*
nativeWindow
=
OH_NativeWindow_CreateNativeWindow
(
&
pSurface
);
```
2.
**设置NativeWindowBuffer的属性**
。使用
`OH_NativeWindow_NativeWindowHandleOpt`
设置
`NativeWindowBuffer`
的属性。
```
c++
// 定义 napi instance
napi_value exportInstance = nullptr;
// 定义一个 OH_NativeXComponent 实例
OH_NativeXComponent *nativeXComponent = nullptr;
// 通过 OH_NATIVE_XCOMPONENT_OBJ export 实例
napi_getname_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
// 将 napi instance 转化为 OH_NativeXComponent 实例
napi_unwarp(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
// 设置 NativeWindowBuffer 的读写场景
int
code
=
SET_USAGE
;
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
height
=
0x100
;
ret
=
OH_NativeWindow_NativeWindowHandleOpt
(
nativeWindow
,
code
,
width
,
height
);
// 设置 NativeWindowBuffer 的步长
code
=
SET_STRIDE
;
int32_t
stride
=
0x8
;
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.
**定义回调函数OnSurfaceCreated**
。用于在
`Surface`
创建时,通过回调函数初始化开发者的渲染环境,例如
`Skia`
渲染环境。并将要显示的内容写入
`NativeWindow`
:
3.
**从图形队列申请NativeWindowBuffer**
。
```
c++
struct
NativeWindowBuffer
*
buffer
=
nullptr
;
int
fenceFd
;
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 NativeWindowBuffer 实例
OH_NativeWindow_NativeWindowRequestBuffer
(
nativeWindow_
,
&
buffer
,
&
fenceFd
);
// 通过 OH_NativeWindow_GetNativeBufferHandleFromNative 获取 buffer 的 handle
BufferHandle
*
bufferHandle
=
OH_NativeWindow_GetNativeBufferHandleFromNative
(
buffer
);
```
4.
**将生产的内容写入NativeWindowBuffer**
。
```
c++
void OnSurfaceCreatedCB(NativeXComponent* component, void* window) {
//获取 native window 的宽高
uint64_t width_ = 0, height_ = 0;
OH_NativeXComponent_GetXComponentSize(nativeXComponent, window, &width_, &height_);
// 将void* 转换为 NativeWindow 实例,NativeWindow 定义在 native_window/external_window.h 中
NativeWindow* nativeWindow_ = (NativeWindow*)(window);
// 通过 OH_NativeWindow_NativeWindowHandleOpt 设置或者获取NativeWindow的属性
// 1.通过 SET_USAGE 设置 Native Window 的 usage 属性, 例如:HBM_USE_CPU_READ
OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_USAGE, HBM_USE_CPU_READ | HBM_USE_CPU_WRITE |HBM_USE_MEM_DMA);
// 2.通过 SET_BUFFER_GEOMETRY 设置 Native Window 的 宽高属性
OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_BUFFER_GEOMETRY, width_, height_);
// 3.通过 SET_FORMAT 设置 Native Window 的 format 属性, 例如:PIXEL_FMT_RGBA_8888
OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_FORMAT, PIXEL_FMT_RGBA_8888);
// 4.通过 SET_STRIDE 设置 Native Window 的 stride 属性
OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_STRIDE, 0x8);
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 NativeWindowBuffer 实例
struct NativeWindowBuffer* buffer = nullptr;
int fenceFd;
OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer, &fenceFd);
// 通过 OH_NativeWindow_GetNativeBufferHandleFromNative 获取 buffer handle
BufferHandle* bufferHandle = OH_NativeWindow_GetNativeBufferHandleFromNative(buffer);
// 通过 BufferHandle 创建Skia Bitmap
SkBitmap bitmap;
SkImageInfo imageInfo = ...
bitmap.setInfo(imageInfo, bufferHandle->stride);
bitmap.setPixels(bufferHandle->virAddr);
//创建 Skia Canvas 并将内容写入native window
...
//写入完成后,通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上
Region region{nullptr, 0};
OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region)
auto
image
=
static_cast
<
uint8_t
*>
(
buffer
->
sfbuffer
->
GetVirAddr
());
static
uint32_t
value
=
0x00
;
value
++
;
uint32_t
*
pixel
=
static_cast
<
uint32_t
*>
(
image
);
for
(
uint32_t
x
=
0
;
x
<
width
;
x
++
)
{
for
(
uint32_t
y
=
0
;
y
<
height
;
y
++
)
{
*
pixel
++
=
value
;
}
}
```
4.
**注册回调函数OnSurfaceCreated等**
。使用
`OH_NativeXComponent_RegisterCallback`
接口注册上一步中创建的回调函数
。
5.
**提交NativeWindowBuffer到图形队列**
。
```c++
OH_NativeXComponent_Callback &callback_;
callback_->OnSurfaceCreated = OnSurfaceCreatedCB;
callback_->OnSurfaceChanged = OnSurfaceChangedCB;
callback_->OnSurfaceDestroyed = OnSurfaceDestroyedCB;
callback_->DispatchTouchEvent = DispatchTouchEventCB;
OH_NativeXComponent_RegisterCallback(nativeXComponent, callback_)
// 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为NativeWindowBuffer全部有内容更改。
Region region{nullptr, 0};
// 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region);
```
## 相关实例
针对NativeWindow的使用,有以下相关实例可供参考:
-
[
使用NativeWindow接口获取Buffer
](
https://gitee.com/openharmony/graphic_graphic_2d/blob/master/rosen/samples/hello_native_window/hello_native_window.cpp
)
-
[
使用NativeWindow接口获取
并提交
Buffer
](
https://gitee.com/openharmony/graphic_graphic_2d/blob/master/rosen/samples/hello_native_window/hello_native_window.cpp
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录