1# 请求自绘制内容绘制帧率 2 3对于基于[XComponent](../ui/napi-xcomponent-guidelines.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 import XComponentContext from "../interface/XComponentContext"; 31 32 @Entry 33 @Component 34 struct Index { 35 private xComponentContext1: XComponentContext | undefined = undefined; 36 private xComponentContext2: XComponentContext | undefined = undefined; 37 38 build() { 39 Column() { 40 Row() { 41 XComponent({ id: 'xcomponentId_30', type: 'surface', libraryname: 'entry' }) 42 .onLoad((xComponentContext) => { 43 this.xComponentContext1 = xComponentContext as XComponentContext; 44 }).width('832px') 45 }.height('40%') 46 47 Row() { 48 XComponent({ id: 'xcomponentId_120', type: 'surface', libraryname: 'entry' }) 49 .onLoad((xComponentContext) => { 50 this.xComponentContext2 = xComponentContext as XComponentContext; 51 }).width('832px') // Multiples of 64 52 }.height('40%') 53 } 54 } 55 } 56 ``` 57 583. Native层配置帧率和注册回调函数。 59 60 ```ts 61 static void TestCallback(OH_NativeXComponent *component, uint64_t timestamp, uint64_t targetTimestamp) // 定义每帧的回调函数 62 { 63 // ... 64 // 获取XComponent的surface大小 65 int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, nativeWindow, &width, &height); 66 if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) { 67 render->Prepare(); 68 render->Create(); 69 if (id == "xcomponentId_30") { 70 // 30Hz绘制时,每帧移动的距离为16像素 71 render->ConstructPath(16, 16, render->defaultOffsetY); 72 } 73 if (id == "xcomponentId_120") { 74 // 120Hz绘制时,每帧移动的距离为4像素 75 render->ConstructPath(4, 4, render->defaultOffsetY); 76 } 77 // ... 78 } 79 } 80 ``` 81 82 > **说明:** 83 > 84 > - Callback回调函数运行于UI主线程,故涉及UI线程的耗时操作不应运行于回调函数中,以免影响性能。 85 > - 实例在调用NapiRegister后,在不需要进行帧率控制时,应进行NapiUnregister操作,避免内存泄漏问题。 86 87 ```ts 88 void SampleXComponent::RegisterOnFrameCallback(OH_NativeXComponent *nativeXComponent) 89 { 90 OH_NativeXComponent_RegisterOnFrameCallback(nativeXComponent, TestCallback); // 注册回调函数,并使能每帧回调 91 } 92 93 napi_value SampleXComponent::NapiRegister(napi_env env, napi_callback_info info) 94 { 95 // ... 96 render->RegisterOnFrameCallback(nativeXComponent); // 在TS层使能注册与使能每帧回调 97 // ... 98 } 99 100 napi_value SampleXComponent::NapiUnregister(napi_env env, napi_callback_info info) 101 { 102 // ... 103 OH_NativeXComponent_UnregisterOnFrameCallback(nativeXComponent); // 在TS层取消注册每帧回调 104 // ... 105 } 106 ``` 107 1084. TS层注册和取消注册每帧回调。 109 110 ```ts 111 Row() { 112 Button('Start') 113 .id('Start') 114 .fontSize(14) 115 .fontWeight(500) 116 .margin({ bottom: 20, right: 6, left: 6 }) 117 .onClick(() => { 118 if (this.xComponentContext1) { 119 this.xComponentContext1.register(); 120 } 121 if (this.xComponentContext2) { 122 this.xComponentContext2.register(); 123 } 124 }) 125 .width('30%') 126 .height(40) 127 .shadow(ShadowStyle.OUTER_DEFAULT_LG) 128 129 Button('Stop') 130 .id('Stop') 131 .fontSize(14) 132 .fontWeight(500) 133 .margin({ bottom: 20, left: 6 }) 134 .onClick(() => { 135 if (this.xComponentContext1) { 136 this.xComponentContext1.unregister(); 137 } 138 if (this.xComponentContext2) { 139 this.xComponentContext2.unregister(); 140 } 141 }) 142 .width('30%') 143 .height(40) 144 .shadow(ShadowStyle.OUTER_DEFAULT_LG) 145 } 146 ``` 147 148## 相关实例 149 150针对可变帧率的开发,有以下相关实例可供参考: 151 152- [DisplaySync分级管控(ArkTS)(API11)](https://gitee.com/openharmony/applications_app_samples/tree/master/code/BasicFeature/Graphics/DisplaySync)