• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 请求自绘制内容绘制帧率
2<!--Kit: ArkGraphics 2D-->
3<!--Subsystem: Graphics-->
4<!--Owner: @hudi33-->
5<!--Designer: @hudi33-->
6<!--Tester: @zhaoxiaoguang2-->
7<!--Adviser: @ge-yafang-->
8
9对于基于[XComponent](../ui/napi-xcomponent-guidelines.md)进行Native开发的业务,可以请求独立的绘制帧率进行内容开发,如游戏、自绘制UI框架对接等场景。
10
11## 接口说明
12
13| 函数名称  | 说明     |
14|-----|--------|
15| OH_NativeXComponent_SetExpectedFrameRateRange (OH_NativeXComponent *component, OH_NativeXComponent_ExpectedRateRange *range) |设置帧期望的帧率范围。
16| OH_NativeXComponent_RegisterOnFrameCallback (OH_NativeXComponent *component, OH_NativeXComponent_OnFrameCallback *callback) | 设置每帧回调函数,同时启动每帧回调。 |
17| OH_NativeXComponent_UnRegisterOnFrameCallback (OH_NativeXComponent *component) | 取消注册的每帧回调函数,同时停止调用回调函数。 |
18
19详细的接口说明请参考[OH_NativeXComponent Native XComponent](../reference/apis-arkui/capi-oh-nativexcomponent-native-xcomponent.md)。
20
21## 开发步骤
22
23   > **说明:**
24   >
25   > 本范例是通过Drawing在Native侧实现图形的绘制,并将其呈现在NativeWindow上,具体可参考[使用Drawing实现图形绘制与显示](graphic-drawing-overview.md)。
26
271. 添加开发依赖。
28
29   CMakeLists.txt中添加以下lib。
30
31   ```txt
32   libace_napi.z.so
33   libace_ndk.z.so
34   libnative_window.so
35   libnative_drawing.so
36   ```
37
38   导入依赖的相关头文件。
39
40   ```c++
41   #include <ace/xcomponent/native_interface_xcomponent.h>
42   #include "napi/native_api.h"
43   #include <native_drawing/drawing_bitmap.h>
44   #include <native_drawing/drawing_color.h>
45   #include <native_drawing/drawing_canvas.h>
46   #include <native_drawing/drawing_pen.h>
47   #include <native_drawing/drawing_brush.h>
48   #include <native_drawing/drawing_path.h>
49   #include <native_drawing/drawing_text_typography.h>
50   #include <native_window/external_window.h>
51   #include <cmath>
52   #include <algorithm>
53   #include <stdint.h>
54   #include <sys/mman.h>
55   ```
56
572. 定义ArkTS接口文件XComponentContext.ts,用来对接Native层。
58   ```ts
59   export default interface XComponentContext {
60   register(): void;
61   unregister(): void;
62   };
63   ```
64
653. 定义演示页面,包含两个XComponent组件。
66
67   ```ts
68   import XComponentContext from "../interface/XComponentContext";
69
70   @Entry
71   @Component
72   struct Index {
73     private xComponentContext1: XComponentContext | undefined = undefined;
74     private xComponentContext2: XComponentContext | undefined = undefined;
75
76    build() {
77      Column() {
78        Row() {
79          XComponent({ id: 'xcomponentId_30', type: XComponentType.SURFACE, libraryname: 'entry' })
80            .onLoad((xComponentContext) => {
81              this.xComponentContext1 = xComponentContext as XComponentContext;
82            }).width('832px')
83        }.height('40%')
84
85        Row() {
86          XComponent({ id: 'xcomponentId_120', type: XComponentType.SURFACE, libraryname: 'entry' })
87            .onLoad((xComponentContext) => {
88              this.xComponentContext2 = xComponentContext as XComponentContext;
89            }).width('832px') // Multiples of 64
90        }.height('40%')
91      }
92    }
93   }
94   ```
95
964. Native层配置帧率和注册回调函数。
97
98   ```ts
99   static void TestCallback(OH_NativeXComponent *component, uint64_t timestamp, uint64_t targetTimestamp) // 定义每帧的回调函数
100   {
101       // ...
102       // 获取XComponent的surface大小
103       int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, nativeWindow, &width, &height);
104       if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
105           render->Prepare();
106           render->Create();
107           if (id == "xcomponentId_30") {
108               // 30Hz绘制时,每帧移动的距离为16像素
109               render->ConstructPath(16, 16, render->defaultOffsetY);
110           }
111           if (id == "xcomponentId_120") {
112               // 120Hz绘制时,每帧移动的距离为4像素
113               render->ConstructPath(4, 4, render->defaultOffsetY);
114           }
115     	 // ...
116       }
117   }
118   ```
119
120   > **说明:**
121   >
122   > - Callback回调函数运行于UI主线程,故涉及UI线程的耗时操作不应运行于回调函数中,以免影响性能。
123   > - 实例在调用OH_NativeXComponent_RegisterOnFrameCallback后,在不需要进行帧率控制时,应进行OH_NativeXComponent_UnregisterOnFrameCallback操作,避免内存泄漏及性能功耗影响。
124   > - API version 18之前,应用调用OH_NativeXComponent_RegisterOnFrameCallback接口设置回调函数,如果没有取消注册,在XComponent实例存在期间,能一直收到期望回调。
125   > - 从API version 18开始,应用调用OH_NativeXComponent_RegisterOnFrameCallback接口设置回调函数,如果没有取消注册,只在XComponent上树期间,能收到期望回调。
126
127   ```ts
128   void SampleXComponent::RegisterOnFrameCallback(OH_NativeXComponent *nativeXComponent)
129   {
130       OH_NativeXComponent_RegisterOnFrameCallback(nativeXComponent, TestCallback); // 注册回调函数,并使能每帧回调
131   }
132
133   napi_value SampleXComponent::NapiRegister(napi_env env, napi_callback_info info)
134   {
135       // ...
136       render->RegisterOnFrameCallback(nativeXComponent); // 在TS层使能注册与使能每帧回调
137       // ...
138   }
139
140   napi_value SampleXComponent::NapiUnregister(napi_env env, napi_callback_info info)
141   {
142       // ...
143       OH_NativeXComponent_UnregisterOnFrameCallback(nativeXComponent); // 在TS层取消注册每帧回调
144       // ...
145   }
146   ```
147
1485. TS层注册和取消注册每帧回调。
149
150   ```ts
151   Row() {
152       Button('Start')
153         .id('Start')
154         .fontSize(14)
155         .fontWeight(500)
156         .margin({ bottom: 20, right: 6, left: 6 })
157         .onClick(() => {
158           if (this.xComponentContext1) {
159             this.xComponentContext1.register();
160           }
161           if (this.xComponentContext2) {
162             this.xComponentContext2.register();
163           }
164         })
165         .width('30%')
166         .height(40)
167         .shadow(ShadowStyle.OUTER_DEFAULT_LG)
168
169       Button('Stop')
170         .id('Stop')
171         .fontSize(14)
172         .fontWeight(500)
173         .margin({ bottom: 20, left: 6 })
174         .onClick(() => {
175           if (this.xComponentContext1) {
176             this.xComponentContext1.unregister();
177           }
178           if (this.xComponentContext2) {
179             this.xComponentContext2.unregister();
180           }
181         })
182         .width('30%')
183         .height(40)
184         .shadow(ShadowStyle.OUTER_DEFAULT_LG)
185   }
186   ```
187
188<!--RP1-->
189## 相关实例
190
191- [DisplaySync (API14)](https://gitcode.com/openharmony/applications_app_samples/tree/master/code/DocsSample/graphic/DisplaySync)
192<!--RP1End-->