1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "charger_graphic_engine.h"
16 #include "charger_log.h"
17 #include "common/graphic_startup.h"
18 #include "common/image_decode_ability.h"
19 #include "common/task_manager.h"
20 #include "draw/draw_utils.h"
21 #include "font/ui_font_header.h"
22
23 #include <cinttypes>
24
25 namespace OHOS {
26 namespace PowerMgr {
GetInstance()27 ChargerGraphicEngine& ChargerGraphicEngine::GetInstance()
28 {
29 static ChargerGraphicEngine instance;
30 static bool isRegister = false;
31 if (!isRegister) {
32 OHOS::SoftEngine::InitGfxEngine(&instance);
33 isRegister = true;
34 }
35
36 return instance;
37 }
38
Init(uint32_t bkgColor,uint8_t mode,const char * fontPath,const char * ttfName)39 void ChargerGraphicEngine::Init(uint32_t bkgColor, uint8_t mode, const char* fontPath, const char* ttfName)
40 {
41 bkgColor_ = bkgColor;
42 colorMode_ = mode;
43 [[maybe_unused]] static bool initOnce = [this, fontPath, ttfName]() {
44 sfDev_ = std::make_unique<GraphicDev>();
45 if (!sfDev_->Init()) {
46 BATTERY_HILOGE(FEATURE_CHARGING, "ChargerGraphicEngine::Init failed");
47 return false;
48 }
49 sfDev_->GetScreenSize(width_, height_);
50 buffInfo_ = nullptr;
51 virAddr_ = nullptr;
52 InitFontEngine(fontPath, ttfName);
53 InitImageDecodeAbility();
54 InitFlushThread();
55 return true;
56 }();
57 }
58
InitFontEngine(const char * fontPath,const char * ttfName)59 void ChargerGraphicEngine::InitFontEngine(const char* fontPath, const char* ttfName)
60 {
61 constexpr uint32_t uiFontMemAlignment = 4;
62 static uint32_t fontMemBaseAddr[OHOS::MIN_FONT_PSRAM_LENGTH / uiFontMemAlignment];
63 static uint8_t icuMemBaseAddr[OHOS::SHAPING_WORD_DICT_LENGTH];
64 OHOS::GraphicStartUp::InitFontEngine(
65 reinterpret_cast<uintptr_t>(fontMemBaseAddr), OHOS::MIN_FONT_PSRAM_LENGTH, fontPath, ttfName);
66 OHOS::GraphicStartUp::InitLineBreakEngine(reinterpret_cast<uintptr_t>(icuMemBaseAddr),
67 OHOS::SHAPING_WORD_DICT_LENGTH, fontPath, DEFAULT_LINE_BREAK_RULE_FILENAME);
68 }
69
InitImageDecodeAbility()70 void ChargerGraphicEngine::InitImageDecodeAbility()
71 {
72 uint32_t imageType = OHOS::IMG_SUPPORT_BITMAP | OHOS::IMG_SUPPORT_JPEG | OHOS::IMG_SUPPORT_PNG;
73 OHOS::ImageDecodeAbility::GetInstance().SetImageDecodeAbility(imageType);
74 }
75
InitFlushThread()76 void ChargerGraphicEngine::InitFlushThread()
77 {
78 flushStop_ = false;
79 flushLoop_ = std::thread(&ChargerGraphicEngine::FlushThreadLoop, this);
80 flushLoop_.detach();
81 }
82
UsSleep(int usec)83 void ChargerGraphicEngine::UsSleep(int usec)
84 {
85 constexpr int USECONDS_PER_SECONDS = 1000000; // 1s = 1000000us
86 constexpr int NANOSECS_PER_USECONDS = 1000; // 1us = 1000ns
87 auto seconds = usec / USECONDS_PER_SECONDS;
88 long nanoSeconds = static_cast<long>(usec) % USECONDS_PER_SECONDS * NANOSECS_PER_USECONDS;
89 struct timespec ts = {static_cast<time_t>(seconds), nanoSeconds};
90 while (nanosleep(&ts, &ts) < 0 && errno == EINTR) {}
91 }
92
FlushThreadLoop()93 void ChargerGraphicEngine::FlushThreadLoop()
94 {
95 while (!flushStop_) {
96 OHOS::TaskManager::GetInstance()->TaskHandler();
97 UsSleep(THREAD_USLEEP_TIME);
98 }
99 }
100
GetFBBufferInfo()101 OHOS::BufferInfo* ChargerGraphicEngine::GetFBBufferInfo()
102 {
103 if (buffInfo_ != nullptr) {
104 return buffInfo_.get();
105 }
106
107 uint8_t pixelBytes = OHOS::DrawUtils::GetByteSizeByColorMode(colorMode_);
108 if (pixelBytes == 0) {
109 BATTERY_HILOGE(FEATURE_CHARGING, "ChargerGraphicEngine get pixelBytes fail");
110 return nullptr;
111 }
112
113 if ((width_ == 0) || (height_ == 0)) {
114 BATTERY_HILOGE(FEATURE_CHARGING, "input error, width: %{public}d, height: %{public}d", width_, height_);
115 return nullptr;
116 }
117 virAddr_ = std::make_unique<uint8_t[]>(width_ * height_ * pixelBytes);
118 buffInfo_ = std::make_unique<OHOS::BufferInfo>();
119 buffInfo_->rect = {0, 0, static_cast<int16_t>(width_ - 1), static_cast<int16_t>(height_ - 1)};
120 buffInfo_->mode = static_cast<OHOS::ColorMode>(colorMode_);
121 buffInfo_->color = bkgColor_;
122 buffInfo_->virAddr = virAddr_.get();
123 buffInfo_->phyAddr = buffInfo_->virAddr;
124 buffInfo_->stride = static_cast<uint32_t>(width_ * pixelBytes);
125 buffInfo_->width = width_;
126 buffInfo_->height = height_;
127 return buffInfo_.get();
128 }
129
Flush(const OHOS::Rect & flushRect)130 void ChargerGraphicEngine::Flush(const OHOS::Rect& flushRect)
131 {
132 if ((sfDev_ == nullptr) || (buffInfo_ == nullptr)) {
133 BATTERY_HILOGE(FEATURE_CHARGING, "null error");
134 return;
135 }
136 std::lock_guard<std::mutex> lock {mtx_};
137 sfDev_->Flip(reinterpret_cast<const uint8_t*>(buffInfo_->virAddr));
138 }
139
GetScreenWidth()140 uint16_t ChargerGraphicEngine::GetScreenWidth()
141 {
142 return width_;
143 }
144
GetScreenHeight()145 uint16_t ChargerGraphicEngine::GetScreenHeight()
146 {
147 return height_;
148 }
149 } // namespace PowerMgr
150 } // namespace OHOS
151