鸿蒙实战开发5.0版:小型体系图形框架集成

打印 上一主题 下一主题

主题 499|帖子 499|积分 1497

  鸿蒙NEXT开发实战往期必看文章:

HarmonyOS NEXT应用开发性能优化实践总结(持续更新......)

HarmonyOS NEXT应用开发案例实践总结合集(持续更新......)
一分钟了解”纯血版!鸿蒙HarmonyOS Next应用开发!
“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线!(从零底子入门到精通)

当前,小型体系图形模块以子体系的形式在 OpenHarmony 中运行。开发者只需适配实现OpenHarmony HDF 层 API 即可。由于利用场景不同,图形子体系也支持在不同平台集成运行。例如,在 Windows/Mac 上开发应用程序时,可以利用 QT Creator 进行简朴的页面布局、开发和调试。此时,图形子体系已经适配到了 Windows/Mac 平台上运行。如果想要将图形子体系独立集成到现有项目中,则需要进行一些简朴的适配工作,并分为以下几个重要部分:

  • 引擎初始化
  • 体现设备适配
  • 输入设备适配
  • 字体初始化
  • 屏幕革新对接
具体步骤如下,步骤末了有参考示例代码,具体可参照 OpenHarmony 小型体系图形 Simulator 适配实现。
图形引擎初始化

重要包括初始化 UI 任务、渲染模块、动画模块、默认样式等
  1. // graphic_startup.h
  2. GraphicStartUp::Init();
  3. <strong>c++</strong>
复制代码
体现设备适配

重要包括设置屏幕大小,对接底子图元绘制,获取图形绘制的 buffer,把图形绘制的数据刷到屏幕上体现等。
体现层适配根据硬件绘制和软件绘制不同,需继续实现不同的类。此中 gfx_engine_manager.h 中的 BaseGfxEngine 类为纯虚实现,只定义了接口,不含任何实现,适互助为自行实现的硬件绘制的父类; soft_engine.h 中的 SoftEngine 继续自 BaseGfxEngine,对 BaseGfxEngine 的接口进行了软件层实现,适互助为软件绘制的父类。
BaseGfxEngine 类中有3类接口:
第一类:获取显存、申请缓存、开释缓存;
第二类:绘制类底子接口,例如:画线、Blit、Fill 等;
第三类:送显接口,调用该接口完成把绘制内容送显。
此中获取显存和送显接口为移植不同平台必须实现的,第二类接口,图形 UI 框架有默认软件实现,具体在 soft_engine.h 的 SoftEngine 中,软件绘制可继续 SoftEngine 进行功能拓展;不同平台如有硬件加速,例如 DMA2D,可继续 gfx_engine_manager.h 的 BaseGfxEngine,对其纯虚方法进行全部实现后,进行扩展性适配。
图形对接接口代码如下:
  1. // gfx_engine_manager.h
  2. virtual void DrawArc(BufferInfo& dst,
  3.                         ArcInfo& arcInfo,
  4.                         const Rect& mask,
  5.                         const Style& style,
  6.                         OpacityType opacity,
  7.                         uint8_t cap) = 0;
  8. virtual void DrawLine(BufferInfo& dst,
  9.                         const Point& start,
  10.                         const Point& end,
  11.                         const Rect& mask,
  12.                         int16_t width,
  13.                         ColorType color,
  14.                         OpacityType opacity) = 0;
  15. virtual void DrawLetter(BufferInfo& gfxDstBuffer,
  16.                         const uint8_t* fontMap,
  17.                         const Rect& fontRect,
  18.                         const Rect& subRect,
  19.                         const uint8_t fontWeight,
  20.                         const ColorType& color,
  21.                         const OpacityType opa) = 0;
  22. virtual void DrawCubicBezier(BufferInfo& dst,
  23.                                 const Point& start,
  24.                                 const Point& control1,
  25.                                 const Point& control2,
  26.                                 const Point& end,
  27.                                 const Rect& mask,
  28.                                 int16_t width,
  29.                                 ColorType color,
  30.                                 OpacityType opacity) = 0;
  31. virtual void
  32.     DrawRect(BufferInfo& dst, const Rect& rect, const Rect& dirtyRect, const Style& style, OpacityType opacity) = 0;
  33. virtual void DrawTransform(BufferInfo& dst,
  34.                             const Rect& mask,
  35.                             const Point& position,
  36.                             ColorType color,
  37.                             OpacityType opacity,
  38.                             const TransformMap& transMap,
  39.                             const TransformDataInfo& dataInfo) = 0;
  40. // x/y: center of a circle
  41. virtual void ClipCircle(const ImageInfo* info, float x, float y, float radius) = 0;
  42. virtual void Blit(BufferInfo& dst,
  43.                     const Point& dstPos,
  44.                     const BufferInfo& src,
  45.                     const Rect& subRect,
  46.                     const BlendOption& blendOption) = 0;
  47. virtual void Fill(BufferInfo& dst, const Rect& fillArea, const ColorType color, const OpacityType opacity) = 0;
  48. virtual void DrawPath(BufferInfo& dst,
  49.                         void* param,
  50.                         const Paint& paint,
  51.                         const Rect& rect,
  52.                         const Rect& invalidatedArea,
  53.                         const Style& style) = 0;
  54. virtual void FillPath(BufferInfo& dst,
  55.                         void* param,
  56.                         const Paint& paint,
  57.                         const Rect& rect,
  58.                         const Rect& invalidatedArea,
  59.                         const Style& style) = 0;
  60. virtual uint8_t* AllocBuffer(uint32_t size, uint32_t usage) = 0;
  61. virtual void FreeBuffer(uint8_t* buffer, uint32_t usage) = 0;
  62. virtual BufferInfo* GetFBBufferInfo()
  63. {
  64.     return nullptr;
  65. }
  66. virtual void AdjustLineStride(BufferInfo& info) {}
  67. virtual void Flush(const Rect& flushRect) {}
  68. virtual uint16_t GetScreenWidth()
  69. {
  70.     return screenWidth_;
  71. }
  72. virtual uint16_t GetScreenHeight()
  73. {
  74.     return screenHeight_;
  75. }
  76. virtual void SetScreenShape(ScreenShape screenShape)
  77. {
  78.     screenShape_ = screenShape;
  79. }
  80. virtual ScreenShape GetScreenShape()
  81. {
  82.     return screenShape_;
  83. }
  84. <strong>c++</strong>
复制代码
输入设备适配

图形框架支持触摸、按键和旋转设备。当前所有输入设备都需要继续 InputDevice 实现 Read 接口。
触摸输入继续 PointerInputDevice 类实现 Read 接口,需要返回 x/y 坐标和按压状态;
按键输入继续 KeyInputDevice 类实现 Read 接口,需要设置 keyId 和按键状态;
旋转输入继续 RotateInputDevice 类实现 Read 接口,需要设置 rotate 值。
InputDevice 设备对接实例代码如下:
  1. // input_device.h Read 接口
  2. /**
  3. * @brief Read data from hardware.User should override this to set data *
  4. * @param [out] input device data. *
  5. * @returns no more data to read if true.
  6. */
  7. virtual bool Read(DeviceData& data) = 0;
  8. // 继承实现 InputDevice 基类的 Read 接口,以触摸事件对接为例,示例代码如下:
  9. class TouchInput : public OHOS::PointerInputDevice {
  10. public:
  11.     TouchInput() {}
  12.     virtual TouchInput() {}
  13.     // implements read fouction
  14.     bool Read(OHOS::DeviceData& data) override
  15.     {
  16.         // set position and state, you should update the value when touch
  17.         data.point.x = g_lastX;
  18.         data.point.y = g_lastY;
  19.         data.state = g_leftButtonDown ? STATE_PRESS : STATE_RELEASE;
  20.         return false;
  21.     }
  22. };
  23. <strong>c++</strong>
复制代码
字体初始化

字体分为点阵字体和矢量字体。
点阵字体:需要利用字体打包工具生成对应字体 font.bin 文件,工具支持打包中英文字体,详细支持字号和 fontId 可以在工具生成的 ui_text_language.h 中查看。
矢量字体:默认注册了 DEFAULT_VECTOR_FONT_FILENAME,如果想利用其他字体,可以调用 RegisterFontInfo 注册其他字体文件。矢量字体剖析和布局需要依靠三方开源软件 freetype 和 icu,如果想支持阿拉伯语等复杂语言需要依靠三软件 harfbuzz,同时打开 ENABLE_SHAPING 和 ENABLE_ICU。
字体初始化接口代码如下:
  1. // graphic_config.h
  2. #define DEFAULT_VECTOR_FONT_FILENAME      "SourceHanSansSC-Regular.otf"
  3. // 矢量字体开关
  4. #define ENABLE_VECTOR_FONT                1
  5. // 点阵字体开关
  6. #define ENABLE_BITMAP_FONT                0
  7. #define ENABLE_ICU                        0
  8. #define ENABLE_SHAPING                    0
  9. // ui_font.h
  10. uint8_t RegisterFontInfo(const char* ttfName, uint8_t shaping = 0)
  11. // graphic_startup.h
  12. static void InitFontEngine(uintptr_t psramAddr, uint32_t psramLen, const char* dPath, const char* ttfName);
  13. <strong>c++</strong>
复制代码
屏幕革新对接

根据屏幕硬件革新信号(类似 Vsync 信号),周期性回调 TaskHandler
屏幕革新对接接口代码如下:
  1. TaskManager::GetInstance()->TaskHandler();
  2. <strong>c++</strong>
复制代码
图形适配示例代码

对接相干宏定义分析如下:
  1. // graphic_config.h
  2. // 默认定义了不同级别设备宏定义,轻设备请启动 VERSION_LITE 宏
  3. /**
  4. * Defines three graphics library versions: lightweight, standard, and extended versions.
  5. * The three versions have different requirements on the memory and hardware.
  6. * The standard version is enabled by default.
  7. *
  8. * The macros of the versions are defined as follows:
  9. * Name                | Version Description
  10. * ------------------- | ----------
  11. * VERSION_LITE        | Lightweight version
  12. * VERSION_STANDARD    | Standard version
  13. * VERSION_EXTENDED    | Extended version
  14. */
  15. #ifdef _LITEOS
  16. #define VERSION_LITE
  17. #elif defined _WIN32 || defined __APPLE__
  18. #define VERSION_LITE
  19. #else
  20. #define VERSION_STANDARD
  21. #endif
  22. // 关闭窗口合成,打开需要依赖 wms 窗口合成服务
  23. /**
  24. * @brief Multi-window, which is disabled by default on WIN32.
  25. */
  26. #define ENABLE_WINDOW                     0
  27. // 关闭 png、jpeg 格式图片支持,打开需要引入三方库
  28. #define ENABLE_JPEG_AND_PNG               0
  29. // 硬件加速,关闭默认走CPU软绘制,可以先关闭,界面显示后再打开适配硬件能力
  30. /**
  31. * @brief Graphics rendering hardware acceleration, which is disabled by default on WIN32.
  32. */
  33. #define ENABLE_HARDWARE_ACCELERATION     0
  34. <strong>c++</strong>
复制代码
对接示例代码如下:
  1. using namespace OHOS;
  2. int main(int argc, char** argv)
  3. {
  4.     // init graphic
  5.     GraphicStartUp::Init();
  6.     // init display/input device
  7.     InitHal();
  8.     // init font engine
  9.     InitFontEngine();
  10.     // run your app code
  11.     RunApp();
  12.     // use while loop to simulate hardware flush callback
  13.     // you should call *TaskHandler* in screen flush signal callback(like Vsync).
  14.     while (1) {
  15.         TaskManager::GetInstance()->TaskHandler();
  16.         Sleep(DEFAULT_TASK_PERIOD);
  17.     }
  18.     return 0;
  19. }
  20. // assuming below are the memory pool
  21. static uint8_t g_fontPsramBaseAddr[MIN_FONT_PSRAM_LENGTH];
  22. #if ENABLE_SHAPING
  23. static uint8_t g_shapePsramBaseAddr[MIN_SHAPING_PSRAM_LENGTH];
  24. #else
  25. static uint8_t* g_shapePsramBaseAddr = nullptr;
  26. #endif
  27. static void InitFontEngine()
  28. {
  29. #if ENABLE_VECTOR_FONT
  30.     GraphicStartUp::InitFontEngine(reinterpret_cast<uintptr_t>(g_fontMemBaseAddr), MIN_FONT_PSRAM_LENGTH, VECTOR_FONT_DIR, DEFAULT_VECTOR_FONT_FILENAME);
  31. #else
  32.     BitmapFontInit();
  33.     std::string dPath(_pgmptr);
  34.     size_t len = dPath.size();
  35.     size_t pos = dPath.find_last_of('\\');
  36.     dPath.replace((pos + 1), (len - pos), "..\\..\\simulator\\font\\font.bin");
  37.     GraphicStartUp::InitFontEngine(reinterpret_cast<uintptr_t>(g_fontMemBaseAddr), MIN_FONT_PSRAM_LENGTH, dPath.c_str(), nullptr);
  38. #endif
  39. #if ENABLE_ICU
  40.     GraphicStartUp::InitLineBreakEngine(reinterpret_cast<uintptr_t>(g_icuMemBaseAddr), SHAPING_WORD_DICT_LENGTH,
  41. VECTOR_FONT_DIR, DEFAULT_LINE_BREAK_RULE_FILENAME);
  42. #endif
  43. }
  44. // display adaptor
  45. class SDLMonitorGfxEngine : public BaseGfxEngine {
  46. public:
  47.     BufferInfo* GetFBBufferInfo() override
  48.     {
  49.         static BufferInfo* bufferInfo = nullptr;
  50.         if (bufferInfo == nullptr) {
  51.             bufferInfo = new BufferInfo;
  52.             bufferInfo->rect = {0, 0, HORIZONTAL_RESOLUTION - 1, VERTICAL_RESOLUTION - 1};
  53.             bufferInfo->mode = ARGB8888;
  54.             bufferInfo->color = 0x44;
  55.             bufferInfo->virAddr = GetFramBuff();
  56.             bufferInfo->phyAddr = bufferInfo->virAddr;
  57.             // 4: bpp
  58.             bufferInfo->stride = HORIZONTAL_RESOLUTION * 4;
  59.             bufferInfo->width = HORIZONTAL_RESOLUTION;
  60.             bufferInfo->height = VERTICAL_RESOLUTION;
  61.         }
  62.         return bufferInfo;
  63.     }
  64.     void Flush() override
  65.     {
  66.         MonitorRenderFinish();
  67.     }
  68. };
  69. class TouchInput : public OHOS::PointerInputDevice {
  70. public:
  71.     TouchInput() {}
  72.     virtual TouchInput() {}
  73.     // implements read function
  74.     bool Read(OHOS::DeviceData& data) override
  75.     {
  76.         // set position x,y and state, you should update the
  77.         // g_lastX/g_lastY/g_leftButtonDown when touch
  78.         data.point.x = g_lastX;
  79.         data.point.y = g_lastY;
  80.         data.state = g_leftButtonDown ? STATE_PRESS : STATE_RELEASE;
  81.         return false;
  82.     }
  83. };
  84. class KeyInput : public OHOS::KeyInputDevice {
  85. public:
  86.     KeyInput();
  87.     virtual ~KeyInput() {}
  88.     // implements read fouction
  89.     bool Read(OHOS::DeviceData& data) override
  90.     {
  91.         data.keyId = g_lastKeyId;
  92.         data.state = g_lastState;
  93.         g_lastState = INVALID_KEY_STATE;
  94.         return false;
  95.     }
  96. };
  97. // other device if you need to add
  98. class XXInput : public OHOS::XXInputDevice {
  99. public:
  100.     KeyInput();
  101.     virtual ~KeyInput() {}
  102.     // implements read fouction
  103.     bool Read(OHOS::DeviceData& data) override
  104.     {
  105.         // set device data info
  106.     }
  107. };
  108. static void InitHal()
  109. {
  110.     // Setup gfxengine
  111.     BaseGfxEngine::GetInstance()->InitEngine(new SDLMonitorGfxEngine());
  112.     // Setup touch device
  113.     TouchInput* touch = new TouchInput();
  114.     InputDeviceManager::GetInstance()->Add(touch);
  115.     // Setup key device if you need
  116.     KeyInput* key = new KeyInput();
  117.     InputDeviceManager::GetInstance()->Add(key);
  118.     // Setup xx device if you need
  119.     XXInput* inputXX = new XXInput();
  120.     InputDeviceManager::GetInstance()->Add(inputXX);
  121. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

星球的眼睛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表