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)