1e41f4b71Sopenharmony_ci# Requesting Frame Rates for Custom Content 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ciWhen 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. 4e41f4b71Sopenharmony_ci 5e41f4b71Sopenharmony_ci## Available APIs 6e41f4b71Sopenharmony_ci 7e41f4b71Sopenharmony_ci| Name | Description | 8e41f4b71Sopenharmony_ci|-----|--------| 9e41f4b71Sopenharmony_ci| OH_NativeXComponent_SetExpectedFrameRateRange (OH_NativeXComponent *component, OH_NativeXComponent_ExpectedRateRange *range) |Sets the expected frame rate range. 10e41f4b71Sopenharmony_ci| OH_NativeXComponent_RegisterOnFrameCallback (OH_NativeXComponent *component, OH_NativeXComponent_OnFrameCallback *callback) | Registers the display update callback and enables the callback for each frame.| 11e41f4b71Sopenharmony_ci| OH_NativeXComponent_UnRegisterOnFrameCallback (OH_NativeXComponent *component) | Deregisters the display update callback and disables the callback for each frame.| 12e41f4b71Sopenharmony_ci 13e41f4b71Sopenharmony_ci## How to Develop 14e41f4b71Sopenharmony_ci 15e41f4b71Sopenharmony_ci > **NOTE** 16e41f4b71Sopenharmony_ci > 17e41f4b71Sopenharmony_ci > 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). 18e41f4b71Sopenharmony_ci 19e41f4b71Sopenharmony_ci1. Define an ArkTS API file and name it **XComponentContext.ts**, which is used to connect to the native layer. 20e41f4b71Sopenharmony_ci ```ts 21e41f4b71Sopenharmony_ci export default interface XComponentContext { 22e41f4b71Sopenharmony_ci register(): void; 23e41f4b71Sopenharmony_ci unregister(): void; 24e41f4b71Sopenharmony_ci }; 25e41f4b71Sopenharmony_ci ``` 26e41f4b71Sopenharmony_ci 27e41f4b71Sopenharmony_ci2. Define a demo page, which contains two **XComponents**. 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci ```ts 30e41f4b71Sopenharmony_ci import XComponentContext from "../interface/XComponentContext"; 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci @Entry 33e41f4b71Sopenharmony_ci @Component 34e41f4b71Sopenharmony_ci struct Index { 35e41f4b71Sopenharmony_ci private xComponentContext1: XComponentContext | undefined = undefined; 36e41f4b71Sopenharmony_ci private xComponentContext2: XComponentContext | undefined = undefined; 37e41f4b71Sopenharmony_ci 38e41f4b71Sopenharmony_ci build() { 39e41f4b71Sopenharmony_ci Column() { 40e41f4b71Sopenharmony_ci Row() { 41e41f4b71Sopenharmony_ci XComponent({ id: 'xcomponentId_30', type: 'surface', libraryname: 'entry' }) 42e41f4b71Sopenharmony_ci .onLoad((xComponentContext) => { 43e41f4b71Sopenharmony_ci this.xComponentContext1 = xComponentContext as XComponentContext; 44e41f4b71Sopenharmony_ci }).width('832px') 45e41f4b71Sopenharmony_ci }.height('40%') 46e41f4b71Sopenharmony_ci 47e41f4b71Sopenharmony_ci Row() { 48e41f4b71Sopenharmony_ci XComponent({ id: 'xcomponentId_120', type: 'surface', libraryname: 'entry' }) 49e41f4b71Sopenharmony_ci .onLoad((xComponentContext) => { 50e41f4b71Sopenharmony_ci this.xComponentContext2 = xComponentContext as XComponentContext; 51e41f4b71Sopenharmony_ci }).width('832px') // Multiples of 64 52e41f4b71Sopenharmony_ci }.height('40%') 53e41f4b71Sopenharmony_ci } 54e41f4b71Sopenharmony_ci } 55e41f4b71Sopenharmony_ci } 56e41f4b71Sopenharmony_ci ``` 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci3. Configure the frame rate and register the callback function at the native layer. 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci ```ts 61e41f4b71Sopenharmony_ci static void TestCallback(OH_NativeXComponent *component, uint64_t timestamp, uint64_t targetTimestamp) // Define the callback function for each frame. 62e41f4b71Sopenharmony_ci { 63e41f4b71Sopenharmony_ci // ... 64e41f4b71Sopenharmony_ci // Obtain the surface size of the XComponent. 65e41f4b71Sopenharmony_ci int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, nativeWindow, &width, &height); 66e41f4b71Sopenharmony_ci if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) { 67e41f4b71Sopenharmony_ci render->Prepare(); 68e41f4b71Sopenharmony_ci render->Create(); 69e41f4b71Sopenharmony_ci if (id == "xcomponentId_30") { 70e41f4b71Sopenharmony_ci // When the frame rate is 30 Hz, the frame moves by 16 pixels at a time. 71e41f4b71Sopenharmony_ci render->ConstructPath(16, 16, render->defaultOffsetY); 72e41f4b71Sopenharmony_ci } 73e41f4b71Sopenharmony_ci if (id == "xcomponentId_120") { 74e41f4b71Sopenharmony_ci // When the frame rate is 120 Hz, the frame moves by 4 pixels at a time. 75e41f4b71Sopenharmony_ci render->ConstructPath(4, 4, render->defaultOffsetY); 76e41f4b71Sopenharmony_ci } 77e41f4b71Sopenharmony_ci // ... 78e41f4b71Sopenharmony_ci } 79e41f4b71Sopenharmony_ci } 80e41f4b71Sopenharmony_ci ``` 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci > **NOTE** 83e41f4b71Sopenharmony_ci > 84e41f4b71Sopenharmony_ci > - 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. 85e41f4b71Sopenharmony_ci > - 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. 86e41f4b71Sopenharmony_ci 87e41f4b71Sopenharmony_ci ```ts 88e41f4b71Sopenharmony_ci void SampleXComponent::RegisterOnFrameCallback(OH_NativeXComponent *nativeXComponent) 89e41f4b71Sopenharmony_ci { 90e41f4b71Sopenharmony_ci OH_NativeXComponent_RegisterOnFrameCallback(nativeXComponent, TestCallback); // Register the callback function and enable callback for each frame. 91e41f4b71Sopenharmony_ci } 92e41f4b71Sopenharmony_ci 93e41f4b71Sopenharmony_ci napi_value SampleXComponent::NapiRegister(napi_env env, napi_callback_info info) 94e41f4b71Sopenharmony_ci { 95e41f4b71Sopenharmony_ci // ... 96e41f4b71Sopenharmony_ci render->RegisterOnFrameCallback(nativeXComponent); // Register the callback function and enable callback for each frame at the TS layer. 97e41f4b71Sopenharmony_ci // ... 98e41f4b71Sopenharmony_ci } 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci napi_value SampleXComponent::NapiUnregister(napi_env env, napi_callback_info info) 101e41f4b71Sopenharmony_ci { 102e41f4b71Sopenharmony_ci // ... 103e41f4b71Sopenharmony_ci The OH_NativeXComponent_UnregisterOnFrameCallback(nativeXComponent); // Deregister the callback function for each frame at the TS layer. 104e41f4b71Sopenharmony_ci // ... 105e41f4b71Sopenharmony_ci } 106e41f4b71Sopenharmony_ci ``` 107e41f4b71Sopenharmony_ci 108e41f4b71Sopenharmony_ci4. Register and deregister the callback function for each frame at the TS layer. 109e41f4b71Sopenharmony_ci 110e41f4b71Sopenharmony_ci ```ts 111e41f4b71Sopenharmony_ci Row() { 112e41f4b71Sopenharmony_ci Button('Start') 113e41f4b71Sopenharmony_ci .id('Start') 114e41f4b71Sopenharmony_ci .fontSize(14) 115e41f4b71Sopenharmony_ci .fontWeight(500) 116e41f4b71Sopenharmony_ci .margin({ bottom: 20, right: 6, left: 6 }) 117e41f4b71Sopenharmony_ci .onClick(() => { 118e41f4b71Sopenharmony_ci if (this.xComponentContext1) { 119e41f4b71Sopenharmony_ci this.xComponentContext1.register(); 120e41f4b71Sopenharmony_ci } 121e41f4b71Sopenharmony_ci if (this.xComponentContext2) { 122e41f4b71Sopenharmony_ci this.xComponentContext2.register(); 123e41f4b71Sopenharmony_ci } 124e41f4b71Sopenharmony_ci }) 125e41f4b71Sopenharmony_ci .width('30%') 126e41f4b71Sopenharmony_ci .height(40) 127e41f4b71Sopenharmony_ci .shadow(ShadowStyle.OUTER_DEFAULT_LG) 128e41f4b71Sopenharmony_ci 129e41f4b71Sopenharmony_ci Button('Stop') 130e41f4b71Sopenharmony_ci .id('Stop') 131e41f4b71Sopenharmony_ci .fontSize(14) 132e41f4b71Sopenharmony_ci .fontWeight(500) 133e41f4b71Sopenharmony_ci .margin({ bottom: 20, left: 6 }) 134e41f4b71Sopenharmony_ci .onClick(() => { 135e41f4b71Sopenharmony_ci if (this.xComponentContext1) { 136e41f4b71Sopenharmony_ci this.xComponentContext1.unregister(); 137e41f4b71Sopenharmony_ci } 138e41f4b71Sopenharmony_ci if (this.xComponentContext2) { 139e41f4b71Sopenharmony_ci this.xComponentContext2.unregister(); 140e41f4b71Sopenharmony_ci } 141e41f4b71Sopenharmony_ci }) 142e41f4b71Sopenharmony_ci .width('30%') 143e41f4b71Sopenharmony_ci .height(40) 144e41f4b71Sopenharmony_ci .shadow(ShadowStyle.OUTER_DEFAULT_LG) 145e41f4b71Sopenharmony_ci } 146e41f4b71Sopenharmony_ci ``` 147e41f4b71Sopenharmony_ci 148