• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 请求自绘制内容绘制帧率
2
3对于基于[XComponent](../ui/arkts-common-components-xcomponent.md)进行Native开发的业务,可以请求独立的绘制帧率进行内容开发,如游戏、自绘制UI框架对接等场景。
4
5## 接口说明
6
7| 函数名称  | 说明     |
8|-----|--------|
9| OH_NativeXComponent_SetExpectedFrameRateRange (OH_NativeXComponent *component, OH_NativeXComponent_ExpectedRateRange *range) |设置帧期望的帧率范围。
10| OH_NativeXComponent_RegisterOnFrameCallback (OH_NativeXComponent *component, OH_NativeXComponent_OnFrameCallback *callback) | 设置每帧回调函数,同时启动每帧回调。 |
11| OH_NativeXComponent_UnRegisterOnFrameCallback (OH_NativeXComponent *component) | 取消注册的每帧回调函数,同时停止调用回调函数。 |
12
13## 开发步骤
14
15   > **说明:**
16   >
17   > 本范例是通过Drawing在Native侧实现图形的绘制,并将其呈现在NativeWindow上,具体可参考[使用Drawing实现图形绘制与显示](drawing-guidelines.md)。
18
191. 定义ArkTS接口文件XComponentContext.ts,用来对接Native层。
20   ```ts
21   export default interface XComponentContext {
22   register(): void;
23   unregister(): void;
24   };
25   ```
26
272. 定义演示页面,包含两个XComponent组件。
28
29   ```ts
30   @Entry
31   @Component
32   struct Index {
33     private xComponentContext1: XComponentContext | undefined = undefined;
34     private xComponentContext2: XComponentContext | undefined = undefined;
35      Row() {
36        XComponent({ id: 'xcomponentId_30', type: 'surface', libraryname: 'entry' })
37          .onLoad((xComponentContext) => {
38            this.xComponentContext1 = xComponentContext as XComponentContext;
39          }).width('832px')
40      }.height('40%')
41
42      Row() {
43        XComponent({ id: 'xcomponentId_120', type: 'surface', libraryname: 'entry' })
44          .onLoad((xComponentContext) => {
45            this.xComponentContext2 = xComponentContext as XComponentContext;
46          }).width('832px')// Multiples of 64
47      }.height('40%')
48   }
49   ```
50
513. Native层配置帧率和注册回调函数。
52
53   ```ts
54   static void TestCallback(OH_NativeXComponent *component, uint64_t timestamp, uint64_t targetTimestamp) // 定义每帧的回调函数
55   {
56       // ...
57       // 获取XComponent的surface大小
58       int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, nativeWindow, &width, &height);
59       if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
60           render->Prepare();
61           render->Create();
62           if (id == "xcomponentId_30") {
63               // 30Hz绘制时,每帧移动的距离为16像素
64               render->ConstructPath(16, 16, render->defaultOffsetY);
65           }
66           if (id == "xcomponentId_120") {
67               // 120Hz绘制时,每帧移动的距离为4像素
68               render->ConstructPath(4, 4, render->defaultOffsetY);
69           }
70     	 // ...
71       }
72   }
73   ```
74
75   > **说明:**
76   >
77   > - Callback回调函数运行于UI主线程,故涉及UI线程的耗时操作不应运行于回调函数中,以免影响性能。
78   > - 实例在调用NapiRegister后,在不需要进行帧率控制时,应进行NapiUnregister操作,避免内存泄漏问题。
79
80   ```ts
81   void SampleXComponent::RegisterOnFrameCallback(OH_NativeXComponent *nativeXComponent)
82   {
83       OH_NativeXComponent_RegisterOnFrameCallback(nativeXComponent, TestCallback); // 注册回调函数,并使能每帧回调
84   }
85
86   napi_value SampleXComponent::NapiRegister(napi_env env, napi_callback_info info)
87   {
88       // ...
89       render->RegisterOnFrameCallback(nativeXComponent); // 在TS层使能注册与使能每帧回调
90       // ...
91   }
92
93   napi_value SampleXComponent::NapiUnregister(napi_env env, napi_callback_info info)
94   {
95       // ...
96       OH_NativeXComponent_UnregisterOnFrameCallback(nativeXComponent); // 在TS层取消注册每帧回调
97       // ...
98   }
99   ```
100
1014. TS层注册和取消注册每帧回调。
102
103   ```ts
104   Row() {
105       Button('Start')
106         .id('Start')
107         .fontSize(14)
108         .fontWeight(500)
109         .margin({ bottom: 20, right: 6, left: 6 })
110         .onClick(() => {
111           if (this.xComponentContext1) {
112             this.xComponentContext1.register();
113           }
114           if (this.xComponentContext2) {
115             this.xComponentContext2.register();
116           }
117         })
118         .width('30%')
119         .height(40)
120         .shadow(ShadowStyle.OUTER_DEFAULT_LG)
121
122       Button('Stop')
123         .id('Stop')
124         .fontSize(14)
125         .fontWeight(500)
126         .margin({ bottom: 20, left: 6 })
127         .onClick(() => {
128           if (this.xComponentContext1) {
129             this.xComponentContext1.unregister();
130           }
131           if (this.xComponentContext2) {
132             this.xComponentContext2.unregister();
133           }
134         })
135         .width('30%')
136         .height(40)
137         .shadow(ShadowStyle.OUTER_DEFAULT_LG)
138   }
139   ```
140
141## 相关实例
142
143针对可变帧率的开发,有以下相关实例可供参考:
144
145- [DisplaySync分级管控(ArkTS)(API11)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Graphics/DisplaySync)