1# Requesting Frame Rates for Custom Content 2 3When you use native APIs to develop an application based on the [XComponent](../ui/napi-xcomponent-guidelines.md), you can request an independent frame rate for custom content in scenarios such as gaming and custom UI framework interconnection. 4 5## Available APIs 6 7| Name | Description | 8|-----|--------| 9| OH_NativeXComponent_SetExpectedFrameRateRange (OH_NativeXComponent *component, OH_NativeXComponent_ExpectedRateRange *range) |Sets the expected frame rate range. 10| OH_NativeXComponent_RegisterOnFrameCallback (OH_NativeXComponent *component, OH_NativeXComponent_OnFrameCallback *callback) | Registers the display update callback and enables the callback for each frame.| 11| OH_NativeXComponent_UnRegisterOnFrameCallback (OH_NativeXComponent *component) | Deregisters the display update callback and disables the callback for each frame.| 12 13## How to Develop 14 15 > **NOTE** 16 > 17 > This section draws a graphic through the native Drawing module and presents it using the native Window module. For details, see [Using Drawing to Draw and Display Graphics](drawing-guidelines.md). 18 191. Define an ArkTS API file and name it **XComponentContext.ts**, which is used to connect to the native layer. 20 ```ts 21 export default interface XComponentContext { 22 register(): void; 23 unregister(): void; 24 }; 25 ``` 26 272. Define a demo page, which contains two **XComponents**. 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. Configure the frame rate and register the callback function at the native layer. 59 60 ```ts 61 static void TestCallback(OH_NativeXComponent *component, uint64_t timestamp, uint64_t targetTimestamp) // Define the callback function for each frame. 62 { 63 // ... 64 // Obtain the surface size of the XComponent. 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 // When the frame rate is 30 Hz, the frame moves by 16 pixels at a time. 71 render->ConstructPath(16, 16, render->defaultOffsetY); 72 } 73 if (id == "xcomponentId_120") { 74 // When the frame rate is 120 Hz, the frame moves by 4 pixels at a time. 75 render->ConstructPath(4, 4, render->defaultOffsetY); 76 } 77 // ... 78 } 79 } 80 ``` 81 82 > **NOTE** 83 > 84 > - The callback function runs in the UI main thread. To avoid adverse impact on the performance, time-consuming operations related to the UI thread should not run in the callback function. 85 > - After the instance calls **NapiRegister**, it must call **NapiUnregister** when it no longer needs to control the frame rate, so as to avoid memory leakage. 86 87 ```ts 88 void SampleXComponent::RegisterOnFrameCallback(OH_NativeXComponent *nativeXComponent) 89 { 90 OH_NativeXComponent_RegisterOnFrameCallback(nativeXComponent, TestCallback); // Register the callback function and enable callback for each frame. 91 } 92 93 napi_value SampleXComponent::NapiRegister(napi_env env, napi_callback_info info) 94 { 95 // ... 96 render->RegisterOnFrameCallback(nativeXComponent); // Register the callback function and enable callback for each frame at the TS layer. 97 // ... 98 } 99 100 napi_value SampleXComponent::NapiUnregister(napi_env env, napi_callback_info info) 101 { 102 // ... 103 The OH_NativeXComponent_UnregisterOnFrameCallback(nativeXComponent); // Deregister the callback function for each frame at the TS layer. 104 // ... 105 } 106 ``` 107 1084. Register and deregister the callback function for each frame at the TS layer. 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