• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 "boot_picture_player.h"
16 
17 #include "event_handler.h"
18 #include "log.h"
19 #include "rs_trace.h"
20 #include "transaction/rs_interfaces.h"
21 
22 namespace OHOS {
23 namespace {
24     const std::string BOOT_PIC_ZIP = "/system/etc/graphic/bootpic.zip";
25 }
26 
BootPicturePlayer(const PlayerParams & params)27 BootPicturePlayer::BootPicturePlayer(const PlayerParams& params)
28 {
29     resPath_ = params.resPath;
30     rsSurface_ = params.rsSurface;
31     InitPicCoordinates(params.screenId);
32 }
33 
Play()34 void BootPicturePlayer::Play()
35 {
36     auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance();
37     int waitVsyncReceiverCreateTime = 0;
38     while (receiver_ == nullptr && waitVsyncReceiverCreateTime < MAX_WAIT_VSYNCRECEIVER_CREATE_TIME) {
39         LOGI("receiver is nullptr, try create again");
40         receiver_ = rsClient.CreateVSyncReceiver("BootAnimation", AppExecFwk::EventHandler::Current());
41         usleep(SLEEP_TIME_US);
42         waitVsyncReceiverCreateTime += SLEEP_TIME_US;
43     }
44 
45     if (receiver_ == nullptr) {
46         LOGI("receiver create fail");
47         Stop();
48         return;
49     }
50 
51     VsyncError ret = receiver_->Init();
52     if (ret) {
53         LOGE("vsync receiver init failed: %{public}d", ret);
54         Stop();
55         return;
56     }
57 
58     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::preload");
59     if (ReadPicZipFile(imageVector_, freq_)) {
60         imgVecSize_ = static_cast<int32_t> (imageVector_.size());
61     } else {
62         LOGE("read pic zip failed");
63         Stop();
64         return;
65     }
66     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
67 
68     OHOS::Rosen::VSyncReceiver::FrameCallback fcb = {
69         .userData_ = this,
70         .callback_ = [this](int64_t, void*) { this->OnVsync(); },
71     };
72     int32_t changeFreq = static_cast<int32_t> (1000.0 / freq_ / 16);
73     ret = receiver_->SetVSyncRate(fcb, changeFreq);
74     if (ret) {
75         LOGE("SetVSyncRate failed: %{public}d %{public}d", ret, freq_);
76         Stop();
77         return;
78     } else {
79         LOGI("SetVSyncRate success: %{public}d, %{public}d", freq_, changeFreq);
80     }
81 }
82 
InitPicCoordinates(Rosen::ScreenId screenId)83 void BootPicturePlayer::InitPicCoordinates(Rosen::ScreenId screenId)
84 {
85     Rosen::RSInterfaces& interface = Rosen::RSInterfaces::GetInstance();
86     Rosen::RSScreenModeInfo modeinfo = interface.GetScreenActiveMode(screenId);
87     windowWidth_ = modeinfo.GetScreenWidth();
88     windowHeight_ = modeinfo.GetScreenHeight();
89     if (windowWidth_ >= windowHeight_) {
90         realHeight_ = windowHeight_;
91         realWidth_ = realHeight_;
92         pointX_ = (windowWidth_ - realWidth_) / NUMBER_TWO;
93     } else {
94         realWidth_ = windowWidth_;
95         realHeight_ = realWidth_;
96         pointY_ = (windowHeight_ - realHeight_) / NUMBER_TWO;
97     }
98 }
99 
ReadPicZipFile(ImageStructVec & imgVec,int32_t & freq)100 bool BootPicturePlayer::ReadPicZipFile(ImageStructVec& imgVec, int32_t& freq)
101 {
102     FrameRateConfig frameConfig;
103     ReadZipFile(GetPicZipPath(), imgVec, frameConfig);
104     int32_t imageNum = static_cast<int32_t>(imgVec.size());
105     if (imageNum < 0) {
106         LOGE("zip pic num is invalid.");
107         return false;
108     }
109 
110     SortZipFile(imgVec);
111 
112     if (CheckFrameRateValid(frameConfig.frameRate)) {
113         freq = frameConfig.frameRate;
114     } else {
115         LOGW("Only Support 30, 60 frame rate: %{public}d", frameConfig.frameRate);
116     }
117     LOGI("read freq: %{public}d, pic num: %{public}d", freq, imageNum);
118     return true;
119 }
120 
GetPicZipPath()121 std::string BootPicturePlayer::GetPicZipPath()
122 {
123     if (!IsFileExisted(resPath_)) {
124         LOGI("pic zip path empty or not exist, use default path");
125         return BOOT_PIC_ZIP;
126     }
127     return resPath_;
128 }
129 
CheckFrameRateValid(int32_t frameRate)130 bool BootPicturePlayer::CheckFrameRateValid(int32_t frameRate)
131 {
132     std::vector<int> freqs = {60, 30};
133     int nCount = std::count(freqs.begin(), freqs.end(), frameRate);
134     return nCount > 0;
135 }
136 
OnVsync()137 void BootPicturePlayer::OnVsync()
138 {
139     PostTask([this] { this->Draw(); });
140 }
141 
Draw()142 bool BootPicturePlayer::Draw()
143 {
144     if (picCurNo_ >= (imgVecSize_ - 1)) {
145         LOGI("play sequence frames end");
146         Stop();
147         return false;
148     }
149     picCurNo_ = picCurNo_ + 1;
150     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw RequestFrame");
151     auto frame = rsSurface_->RequestFrame(windowWidth_, windowHeight_);
152     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
153     if (frame == nullptr) {
154         LOGE("draw frame is nullptr");
155         Stop();
156         return false;
157     }
158     rsSurfaceFrame_ = std::move(frame);
159     auto canvas = rsSurfaceFrame_->GetCanvas();
160     OnDraw(canvas, picCurNo_);
161     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::Draw FlushFrame");
162     rsSurface_->FlushFrame(rsSurfaceFrame_);
163     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
164     return true;
165 }
166 
OnDraw(Rosen::Drawing::CoreCanvas * canvas,int32_t curNo)167 bool BootPicturePlayer::OnDraw(Rosen::Drawing::CoreCanvas* canvas, int32_t curNo)
168 {
169     if (canvas == nullptr) {
170         LOGE("OnDraw canvas is nullptr");
171         Stop();
172         return false;
173     }
174     if (curNo > (imgVecSize_ - 1) || curNo < 0) {
175         Stop();
176         return false;
177     }
178     std::shared_ptr<ImageStruct> imgstruct = imageVector_[curNo];
179     std::shared_ptr<Rosen::Drawing::Image> image = imgstruct->imageData;
180 
181     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::OnDraw in drawRect");
182     Rosen::Drawing::Brush brush;
183     brush.SetColor(Rosen::Drawing::Color::COLOR_BLACK);
184     Rosen::Drawing::Rect bgRect(0.0, 0.0, windowWidth_, windowHeight_);
185     canvas->AttachBrush(brush);
186     canvas->DrawRect(bgRect);
187     canvas->DetachBrush();
188     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
189     ROSEN_TRACE_BEGIN(HITRACE_TAG_GRAPHIC_AGP, "BootAnimation::OnDraw in drawImageRect");
190     Rosen::Drawing::Rect rect(pointX_, pointY_, pointX_ + realWidth_, pointY_ + realHeight_);
191     Rosen::Drawing::SamplingOptions samplingOptions;
192     canvas->DrawImageRect(*image, rect, samplingOptions);
193     imageVector_[curNo].reset();
194     ROSEN_TRACE_END(HITRACE_TAG_GRAPHIC_AGP);
195     return true;
196 }
197 
Stop()198 bool BootPicturePlayer::Stop()
199 {
200     auto runner = AppExecFwk::EventRunner::Current();
201     if (runner == nullptr) {
202         LOGE("runner is null");
203         return false;
204     }
205     runner->Stop();
206     return true;
207 }
208 } // namespace OHOS
209