场景介绍

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

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

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

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

接口说明

接口名

描述

OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow *window, OHNativeWindowBuffer **buffer, int *fenceFd)

通过OHNativeWindow对象申请一块OHNativeWindowBuffer,用以内容生产。

OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow *window, OHNativeWindowBuffer *buffer, int fenceFd, Region region)

通过OHNativeWindow将生产好内容的OHNativeWindowBuffer放回到Buffer队列中,用以内容消费。

OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow *window, int code,...)

设置/获取OHNativeWindow的属性,包括设置/获取宽高、内容格式等。

详细的接口说明请参考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
}

  

HarmonyOS:NativeWindow 开发指导的更多相关文章

  1. 鸿蒙HarmonyOS应用开发落地实践,Harmony Go 技术沙龙落地北京

    12月26日,华为消费者BG软件部开源中心与51CTO Harmony OS技术社区携手,共同主办了主题为"Harmony OS 应用开发落地实践"的 Harmony Go 技术沙 ...

  2. 它来了,它来了,HarmonyOS应用开发在线体验来了

    接下来是我们的两分钟科普,一分钟玩转HarmonyOS应用开发在线体验,一分钟简单了解"一次开发.多设备部署"的原理.萌新的开发者也能第一时间掌握,往下看吧~ 一分钟玩转Harmo ...

  3. 乘风破浪,Windows11设计和开发指导,全新图标字体和云母材质

    Windows11全新的布局设计 Windows 11全新的布局设计已设计为支持现代应用体验.渐进的圆角.嵌套元素和一致的排水沟相结合,营造出柔和.平静.平易近人的效果,强调目的的统一和易用性. ht ...

  4. QtQuick桌面应用程序开发指导 3)达到UI而功能_B 4)动态管理Note物_A

    3.2 把Page Item和Marker Item绑定 之前我们实现了PagePanel组件, 使用了三个state来切换Page组件的opacity属性; 这一步我们会使用Marker和Marke ...

  5. QtQuick桌面应用开发指导 1)关于教程 2)原型和设计 3)实现UI和功能_A

    Release1.0 http://qt-project.org/wiki/developer-guides Qt Quick Application Developer Guide for Desk ...

  6. 前言「HarmonyOS应用开发基础篇」

    场景一.随着智能设备种类的不断增多,我们基本上每人都有好几台智能设备,比如智能手机,平板,耳机,音响,穿戴设备等等.这些设备都具有独立性,偶尔的组合也是我们通过手动去搭配,并且不一定能够完全组合在一起 ...

  7. HarmonyOS应用开发-Component体系介绍(一)

    目录: 1. Component的内部类/接口 2. Component方法简介 3.总结 在HarmonyOS的UI框架中,Component为用户界面提供基本组件,Component类位于ohos ...

  8. 如何进行Hadoop二次开发指导视频下载

    本视频适合对Java有一定了解,熟悉java se的Hadoop爱好者,想对Hadoop进行二次开发.下面是以伪分布为例: 想对Hadoop二次开发:一.首先需要Hadoop和Java之间搭建Ecli ...

  9. DHTMLX Tree中文开发指导

    专业版1.6下载地址(CSDN) http://download.csdn.net/source/1388340 版本号:dhtmlxTree v.1.6 Professional edition b ...

  10. IT增值服务-客户案例(三):合肥薪火科技,Java和P2P网络借贷系统开发指导

    客户整体情况: 合肥薪火科技,是安徽合肥一家主营微信开发和运营的中小企业,http://weimarket.cn/. 这家公司筹备.创立.曲折创业的经历,我一直有关注.因为2个老板,都是我的同学校友, ...

随机推荐

  1. STM32FATFS文件系统移植

    STM32FATFS文件系统移植 1. FATFS简介 FATFS文件系统是一个用于在微控制器上运行的开源文件系统,支持FAT/FATFS.NTFS.exFAT等主流文件系统,且一直保持更新.在此以F ...

  2. spark读取和处理zip、gzip、excel、等各种文件最全的技巧总结

    一.当后缀名为zip.gzip,spark可以自动处理和读取 1.spark非常智能,如果一批压缩的zip和gzip文件,并且里面为一堆text文件时,可以用如下方式读取或者获取读取后的schema ...

  3. SQL SERVER——高可用技术概述

    自从SQL Server 2005以来,微软已经提供了多种高可用性技术来减少宕机时间和增加对业务数据的保护,而随着SQL Server 2008,SQL Server 2008 R2,SQL Serv ...

  4. mysql数据库表或行,被锁,杀死进程

    -- 查询进行 SHOW PROCESSLIST; -- 删除进程 kill 22459; -- 查找正在进行的 select * from information_schema.innodb_trx ...

  5. .net中最简单的http请求调用(比如调用chatgpt的openAI接口)

    支持.Net Core(2.0及以上)/.Net Framework(4.5及以上),可以部署在Docker, Windows, Linux, Mac. http请求调用是开发中经常会用到的功能,因为 ...

  6. 巧用SQL语句中的OR查询完成业务新需求-2022新项目

    一.业务场景 目前参与开发的项目,之前的一个已上线的版本中有一类查询是根据两张表进行LEFT JOIN查询用来取数据, 主表中有一个字段field用来区分不同的数据类型比如说A/B/C.前面的版本中只 ...

  7. vscode 切换项目快捷键 Alt + Shift + P 插件 Project Manager

    vscode 切换项目快捷键 Alt + Shift + P 插件 Project Manager 需求 快速切换同时打开的项目 解决方案 Alt + Shift + P 话说这个插件很早就用了,但是 ...

  8. react 修改页面title - react-document-title

    安装 cnpm install --save react-document-title 引用 import DocumentTitle from 'react-document-title' 代码 & ...

  9. Csharp学习Linq

    Linq的学习 这里继续使用之前文章创建的学生类,首先简单介绍一下linq的使用. Student.cs public class Student { public int Id { get; set ...

  10. Asp-Net-Core开发笔记:实现动态审计日志功能

    前言 最近一直在写 Go 和 Python ,好久没写 C# ,重新回来写 C# 代码时竟有一种亲切感~ 说回正题. 在当今这个数字化迅速发展的时代,每一个操作都可能对业务产生深远的影响,无论是对数据 ...