• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 
16 #include "rs_screen.h"
17 
18 #include <cinttypes>
19 
20 #include "string_utils.h"
21 
22 namespace OHOS {
23 namespace Rosen {
24 using namespace HiviewDFX;
25 
26 namespace impl {
27 namespace detail {
28 template <int ROTATE_DEGREES>
RotateMatrix()29 constexpr SkMatrix RotateMatrix()
30 {
31     return SkMatrix().setRotate(ROTATE_DEGREES);
32 }
33 } // namespace detail
34 
RSScreen(ScreenId id,bool isVirtual,std::shared_ptr<HdiOutput> output,sptr<Surface> surface)35 RSScreen::RSScreen(ScreenId id,
36     bool isVirtual,
37     std::shared_ptr<HdiOutput> output,
38     sptr<Surface> surface)
39     : id_(id),
40       isVirtual_(isVirtual),
41       hdiOutput_(std::move(output)),
42       producerSurface_(std::move(surface))
43 {
44     if (!IsVirtual()) {
45         name_ = "Screen_" + std::to_string(id_);
46         PhysicalScreenInit();
47     }
48 }
49 
RSScreen(const VirtualScreenConfigs & configs)50 RSScreen::RSScreen(const VirtualScreenConfigs &configs)
51     : id_(configs.id),
52       mirrorId_(configs.mirrorId),
53       name_(configs.name),
54       width_(configs.width),
55       height_(configs.height),
56       isVirtual_(true),
57       producerSurface_(configs.surface)
58 {
59 }
60 
~RSScreen()61 RSScreen::~RSScreen() noexcept
62 {
63 }
64 
PhysicalScreenInit()65 void RSScreen::PhysicalScreenInit() noexcept
66 {
67     hdiScreen_ = HdiScreen::CreateHdiScreen(ScreenPhysicalId(id_));
68     if (hdiScreen_ == nullptr) {
69         HiLog::Error(LOG_LABEL, "%{public}s: RSScreen(id %{public}" PRIu64 ") failed to CreateHdiScreens.",
70             __func__, id_);
71         return;
72     }
73 
74     hdiScreen_->Init();
75     if (hdiScreen_->GetScreenSupportedModes(supportedModes_) < 0) {
76         HiLog::Error(LOG_LABEL, "%{public}s: RSScreen(id %{public}" PRIu64 ") failed to GetScreenSupportedModes.",
77             __func__, id_);
78     }
79     if (hdiScreen_->GetScreenCapability(capability_) < 0) {
80         HiLog::Error(LOG_LABEL, "%{public}s: RSScreen(id %{public}" PRIu64 ") failed to GetScreenCapability.",
81             __func__, id_);
82     }
83     auto status = DispPowerStatus::POWER_STATUS_ON;
84     if (hdiScreen_->SetScreenPowerStatus(status) < 0) {
85         HiLog::Error(LOG_LABEL, "%{public}s: RSScreen(id %{public}" PRIu64 ") failed to SetScreenPowerStatus.",
86             __func__, id_);
87     }
88     auto activeMode = GetActiveMode();
89     if (activeMode) {
90         width_ = activeMode->width;
91         height_ = activeMode->height;
92     }
93     if (hdiScreen_->GetScreenPowerStatus(powerStatus_) < 0) {
94         powerStatus_ = static_cast<DispPowerStatus>(INVALID_POWER_STATUS);
95     }
96 }
97 
Id() const98 ScreenId RSScreen::Id() const
99 {
100     return id_;
101 }
102 
MirrorId() const103 ScreenId RSScreen::MirrorId() const
104 {
105     return mirrorId_;
106 }
107 
SetMirror(ScreenId mirrorId)108 void RSScreen::SetMirror(ScreenId mirrorId)
109 {
110     mirrorId_ = mirrorId;
111 }
112 
Name() const113 const std::string& RSScreen::Name() const
114 {
115     return name_;
116 }
117 
Width() const118 uint32_t RSScreen::Width() const
119 {
120     return width_;
121 }
122 
Height() const123 uint32_t RSScreen::Height() const
124 {
125     return height_;
126 }
127 
IsEnable() const128 bool RSScreen::IsEnable() const
129 {
130     if (id_ == INVALID_SCREEN_ID) {
131         return false;
132     }
133 
134     if (!hdiOutput_ && !producerSurface_) {
135         return false;
136     }
137 
138     // [PLANNING]: maybe need more information to judge whether this screen is enable.
139     return true;
140 }
141 
IsVirtual() const142 bool RSScreen::IsVirtual() const
143 {
144     return isVirtual_;
145 }
146 
SetActiveMode(uint32_t modeId)147 void RSScreen::SetActiveMode(uint32_t modeId)
148 {
149     if (IsVirtual()) {
150         HiLog::Warn(LOG_LABEL, "%{public}s: virtual screen not support SetActiveMode.\n", __func__);
151         return;
152     }
153 
154     if (modeId >= supportedModes_.size()) {
155         HiLog::Error(LOG_LABEL, "%{public}s: set fails because the index is out of bounds.\n", __func__);
156         return;
157     }
158     int32_t selectModeId = supportedModes_[modeId].id;
159     if (hdiScreen_->SetScreenMode(static_cast<uint32_t>(selectModeId)) < 0) {
160         HiLog::Error(LOG_LABEL, "%{public}s: Hdi SetScreenMode fails.\n", __func__);
161         return;
162     }
163     auto activeMode = GetActiveMode();
164     if (activeMode) {
165         width_ = activeMode->width;
166         height_ = activeMode->height;
167     }
168 }
169 
GetActiveModePosByModeId(int32_t modeId) const170 int32_t RSScreen::GetActiveModePosByModeId(int32_t modeId) const
171 {
172     decltype(supportedModes_.size()) modeIndex = 0;
173     for (; modeIndex < supportedModes_.size(); ++modeIndex) {
174         if (supportedModes_[modeIndex].id == modeId) {
175             return static_cast<int32_t>(modeIndex);
176         }
177     }
178     return -1;
179 }
180 
SetPowerStatus(uint32_t powerStatus)181 void RSScreen::SetPowerStatus(uint32_t powerStatus)
182 {
183     if (IsVirtual()) {
184         HiLog::Warn(LOG_LABEL, "%{public}s: virtual screen not support SetPowerStatus.\n", __func__);
185         return;
186     }
187 
188     HiLog::Info(LOG_LABEL, "SetPowerStatus, status is %{public}u", powerStatus);
189     if (hdiScreen_->SetScreenPowerStatus(static_cast<DispPowerStatus>(powerStatus)) < 0) {
190         return;
191     }
192 
193     if (powerStatus == DispPowerStatus::POWER_STATUS_ON) {
194         HiLog::Info(LOG_LABEL, "Enable hardware vsync");
195         if (hdiScreen_->SetScreenVsyncEnabled(true) != DISPLAY_SUCCESS) {
196             HiLog::Error(LOG_LABEL, "SetScreenVsyncEnabled failed");
197         }
198     }
199 }
200 
GetActiveMode() const201 std::optional<DisplayModeInfo> RSScreen::GetActiveMode() const
202 {
203     if (IsVirtual()) {
204         HiLog::Warn(LOG_LABEL, "%{public}s: virtual screen not support GetActiveMode.\n", __func__);
205         return {};
206     }
207 
208     uint32_t modeId = 0;
209 
210     if (hdiScreen_ == nullptr) {
211         HiLog::Error(LOG_LABEL, "%{public}s: RSScreen(id %{public}" PRIu64 ") hdiScreen is null.",
212             __func__, id_);
213         return {};
214     }
215 
216     if (hdiScreen_->GetScreenMode(modeId) < 0) {
217         HiLog::Error(LOG_LABEL, "%{public}s: RSScreen(id %{public}" PRIu64 ") GetScreenMode failed.",
218             __func__, id_);
219         return {};
220     }
221 
222     auto iter = std::find_if(supportedModes_.cbegin(), supportedModes_.cend(),
223         [modeId](const auto &mode) { return mode.id == modeId; });
224     if (iter == supportedModes_.cend()) {
225         return {};
226     }
227 
228     return *iter;
229 }
230 
GetSupportedModes() const231 const std::vector<DisplayModeInfo>& RSScreen::GetSupportedModes() const
232 {
233     return supportedModes_;
234 }
235 
GetCapability() const236 const DisplayCapability& RSScreen::GetCapability() const
237 {
238     return capability_;
239 }
240 
GetPowerStatus() const241 uint32_t RSScreen::GetPowerStatus() const
242 {
243     if (IsVirtual()) {
244         HiLog::Warn(LOG_LABEL, "%{public}s: virtual screen not support GetPowerStatus.\n", __func__);
245         return ScreenPowerStatus::INVALID_POWER_STATUS;
246     }
247 
248     DispPowerStatus status;
249     if (hdiScreen_->GetScreenPowerStatus(status) < 0) {
250         return INVALID_POWER_STATUS;
251     }
252     return static_cast<uint32_t>(status);
253 }
254 
GetOutput() const255 std::shared_ptr<HdiOutput> RSScreen::GetOutput() const
256 {
257     return hdiOutput_;
258 }
259 
GetProducerSurface() const260 sptr<Surface> RSScreen::GetProducerSurface() const
261 {
262     return producerSurface_;
263 }
264 
SetProducerSurface(sptr<Surface> producerSurface)265 void RSScreen::SetProducerSurface(sptr<Surface> producerSurface)
266 {
267     producerSurface_ = producerSurface;
268 }
269 
ModeInfoDump(std::string & dumpString)270 void RSScreen::ModeInfoDump(std::string& dumpString)
271 {
272     decltype(supportedModes_.size()) modeIndex = 0;
273     for (; modeIndex < supportedModes_.size(); ++modeIndex) {
274         AppendFormat(dumpString, "  supportedMode[%d]: %dx%d, refreshrate=%d\n",
275                      modeIndex, supportedModes_[modeIndex].width,
276                      supportedModes_[modeIndex].height, supportedModes_[modeIndex].freshRate);
277     }
278     std::optional<DisplayModeInfo> activeMode = GetActiveMode();
279     if (activeMode) {
280         AppendFormat(dumpString, "  activeMode: %dx%d, refreshrate=%d\n",
281             activeMode->width, activeMode->height, activeMode->freshRate);
282     }
283 }
284 
CapabilityTypeDump(InterfaceType capabilityType,std::string & dumpString)285 void RSScreen::CapabilityTypeDump(InterfaceType capabilityType, std::string& dumpString)
286 {
287     dumpString += "type=";
288     switch (capability_.type) {
289         case DISP_INTF_HDMI: {
290             dumpString += "DISP_INTF_HDMI, ";
291             break;
292         }
293         case DISP_INTF_LCD: {
294             dumpString += "DISP_INTF_LCD, ";
295             break;
296         }
297         case DISP_INTF_BT1120: {
298             dumpString += "DISP_INTF_BT1120, ";
299             break;
300         }
301         case DISP_INTF_BT656: {
302             dumpString += "DISP_INTF_BT656, ";
303             break;
304         }
305         default:
306             dumpString += "INVILID_DISP_INTF, ";
307             break;
308     }
309 }
310 
CapabilityDump(std::string & dumpString)311 void RSScreen::CapabilityDump(std::string& dumpString)
312 {
313     AppendFormat(dumpString, "  capability: name=%s, phywidth=%d, phyheight=%d,"
314                  "supportlayers=%d, virtualDispCount=%d, propCount=%d, ",
315                  capability_.name, capability_.phyWidth, capability_.phyHeight,
316                  capability_.supportLayers, capability_.virtualDispCount, capability_.propertyCount);
317     CapabilityTypeDump(capability_.type, dumpString);
318     dumpString += "supportWriteBack=";
319     dumpString += (capability_.supportWriteBack) ? "true" : "false";
320     dumpString += "\n";
321     PropDump(dumpString);
322 }
323 
PropDump(std::string & dumpString)324 void RSScreen::PropDump(std::string& dumpString)
325 {
326     decltype(capability_.propertyCount) propIndex = 0;
327     for (; propIndex < capability_.propertyCount; ++propIndex) {
328         AppendFormat(dumpString, "prop[%u]: name=%s, propid=%d, value=%d\n",
329                      propIndex, capability_.props[propIndex].name, capability_.props[propIndex].propId,
330                      capability_.props[propIndex].value);
331     }
332 }
333 
PowerStatusDump(DispPowerStatus powerStatus,std::string & dumpString)334 void RSScreen::PowerStatusDump(DispPowerStatus powerStatus, std::string& dumpString)
335 {
336     dumpString += "powerstatus=";
337     switch (powerStatus) {
338         case POWER_STATUS_ON: {
339             dumpString += "POWER_STATUS_ON";
340             break;
341         }
342         case POWER_STATUS_STANDBY: {
343             dumpString += "POWER_STATUS_STANDBY";
344             break;
345         }
346         case POWER_STATUS_SUSPEND: {
347             dumpString += "POWER_STATUS_SUSPEND";
348             break;
349         }
350         case POWER_STATUS_OFF: {
351             dumpString += "POWER_STATUS_OFF";
352             break;
353         }
354         case POWER_STATUS_BUTT: {
355             dumpString += "POWER_STATUS_BUTT";
356             break;
357         }
358         default:
359             dumpString += "INVALID_POWER_STATUS";
360             break;
361     }
362 }
363 
364 
DisplayDump(int32_t screenIndex,std::string & dumpString)365 void RSScreen::DisplayDump(int32_t screenIndex, std::string& dumpString)
366 {
367     dumpString += "-- ScreenInfo\n";
368     if (IsVirtual()) {
369         dumpString += "screen[" + std::to_string(screenIndex) + "]: ";
370         dumpString += "id=";
371         dumpString += (id_ == INVALID_SCREEN_ID) ? "INVALID_SCREEN_ID" : std::to_string(id_);
372         dumpString += ", ";
373         dumpString += "mirrorId=";
374         dumpString += (mirrorId_ == INVALID_SCREEN_ID) ? "INVALID_SCREEN_ID" : std::to_string(mirrorId_);
375         dumpString += ", ";
376         AppendFormat(dumpString, "%dx%d, isvirtual=true\n", width_, height_);
377     } else {
378         dumpString += "screen[" + std::to_string(screenIndex) + "]: ";
379         dumpString += "id=";
380         dumpString += (id_ == INVALID_SCREEN_ID) ? "INVALID_SCREEN_ID" : std::to_string(id_);
381         dumpString += ", ";
382         PowerStatusDump(powerStatus_, dumpString);
383         dumpString += "\n";
384         ModeInfoDump(dumpString);
385         CapabilityDump(dumpString);
386     }
387 }
388 
SurfaceDump(int32_t screenIndex,std::string & dumpString)389 void RSScreen::SurfaceDump(int32_t screenIndex, std::string& dumpString)
390 {
391     if (hdiOutput_ == nullptr) {
392         return;
393     }
394     hdiOutput_->Dump(dumpString);
395 }
396 
FpsDump(int32_t screenIndex,std::string & dumpString,std::string & arg)397 void RSScreen::FpsDump(int32_t screenIndex, std::string& dumpString, std::string& arg)
398 {
399     if (hdiOutput_ == nullptr) {
400         return;
401     }
402     hdiOutput_->DumpFps(dumpString, arg);
403 }
404 
SetScreenBacklight(uint32_t level)405 void RSScreen::SetScreenBacklight(uint32_t level)
406 {
407     if (IsVirtual()) {
408         HiLog::Warn(LOG_LABEL, "%{public}s: virtual screen not support SetScreenBacklight.\n", __func__);
409         return;
410     }
411     if (hdiScreen_->SetScreenBacklight(level) < 0) {
412         return;
413     }
414 }
415 
GetScreenBacklight() const416 int32_t RSScreen::GetScreenBacklight() const
417 {
418     if (IsVirtual()) {
419         HiLog::Warn(LOG_LABEL, "%{public}s: virtual screen not support GetScreenBacklight.\n", __func__);
420         return INVALID_BACKLIGHT_VALUE;
421     }
422     uint32_t level = 0;
423     if (hdiScreen_->GetScreenBacklight(level) < 0) {
424         return INVALID_BACKLIGHT_VALUE;
425     }
426     return static_cast<int32_t>(level);
427 }
428 
GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut> & mode) const429 int32_t RSScreen::GetScreenSupportedColorGamuts(std::vector<ScreenColorGamut> &mode) const
430 {
431     if (IsVirtual()) {
432         mode.clear();
433         mode = supportedVirtualColorGamuts_;
434         return StatusCode::SUCCESS;
435     }
436     std::vector<ColorGamut> hdiMode;
437     int32_t result = hdiScreen_->GetScreenSupportedColorGamuts(hdiMode);
438     if (result == DispErrCode::DISPLAY_SUCCESS) {
439         mode.clear();
440         for (auto m : hdiMode) {
441             mode.push_back(static_cast<ScreenColorGamut>(m));
442         }
443         return StatusCode::SUCCESS;
444     }
445     return StatusCode::HDI_ERROR;
446 }
447 
GetScreenColorGamut(ScreenColorGamut & mode) const448 int32_t RSScreen::GetScreenColorGamut(ScreenColorGamut &mode) const
449 {
450     if (IsVirtual()) {
451         mode = supportedVirtualColorGamuts_[currentVirtualColorGamutIdx_];
452         return StatusCode::SUCCESS;
453     }
454     ColorGamut hdiMode;
455     int32_t result = hdiScreen_->GetScreenColorGamut(hdiMode);
456     if (result == DispErrCode::DISPLAY_SUCCESS) {
457         mode = static_cast<ScreenColorGamut>(hdiMode);
458         return StatusCode::SUCCESS;
459     }
460     return StatusCode::HDI_ERROR;
461 }
462 
SetScreenColorGamut(int32_t modeIdx)463 int32_t RSScreen::SetScreenColorGamut(int32_t modeIdx)
464 {
465     if (IsVirtual()) {
466         if (modeIdx >= static_cast<int32_t>(supportedVirtualColorGamuts_.size())) {
467             return StatusCode::INVALID_ARGUMENTS;
468         }
469         currentVirtualColorGamutIdx_ = modeIdx;
470         return StatusCode::SUCCESS;
471     }
472     std::vector<ColorGamut> hdiMode;
473     if (hdiScreen_->GetScreenSupportedColorGamuts(hdiMode) != DispErrCode::DISPLAY_SUCCESS) {
474         return StatusCode::HDI_ERROR;
475     }
476     if (modeIdx >= static_cast<int32_t>(hdiMode.size())) {
477         return StatusCode::INVALID_ARGUMENTS;
478     }
479     int32_t result = hdiScreen_->SetScreenColorGamut(hdiMode[modeIdx]);
480     if (result == DispErrCode::DISPLAY_SUCCESS) {
481         return StatusCode::SUCCESS;
482     }
483     return StatusCode::HDI_ERROR;
484 }
485 
SetScreenGamutMap(ScreenGamutMap mode)486 int32_t RSScreen::SetScreenGamutMap(ScreenGamutMap mode)
487 {
488     if (IsVirtual()) {
489         currentVirtualGamutMap_ = mode;
490         return StatusCode::SUCCESS;
491     }
492     int32_t result = hdiScreen_->SetScreenGamutMap(static_cast<GamutMap>(mode));
493     if (result == DispErrCode::DISPLAY_SUCCESS) {
494         return StatusCode::SUCCESS;
495     }
496     return StatusCode::HDI_ERROR;
497 }
498 
GetScreenGamutMap(ScreenGamutMap & mode) const499 int32_t RSScreen::GetScreenGamutMap(ScreenGamutMap &mode) const
500 {
501     if (IsVirtual()) {
502         mode = currentVirtualGamutMap_;
503         return StatusCode::SUCCESS;
504     }
505     GamutMap hdiMode;
506     int32_t result = hdiScreen_->GetScreenGamutMap(hdiMode);
507     if (result == DispErrCode::DISPLAY_SUCCESS) {
508         mode = static_cast<ScreenGamutMap>(hdiMode);
509         return StatusCode::SUCCESS;
510     }
511     return StatusCode::HDI_ERROR;
512 }
513 
UpdateRotationMatrix()514 void RSScreen::UpdateRotationMatrix()
515 {
516     switch (rotation_) {
517         case ScreenRotation::ROTATION_90: {
518             // rotate 90 degrees anticlockwise
519             rotationMatrix_ = detail::RotateMatrix<-90>().postTranslate(0.0, static_cast<float>(height_));
520             break;
521         }
522         case ScreenRotation::ROTATION_180: {
523             // rotate 180 degrees
524             rotationMatrix_ = detail::RotateMatrix<180>().postTranslate(
525                 static_cast<float>(width_), static_cast<float>(height_));
526             break;
527         }
528         case ScreenRotation::ROTATION_270: {
529             // rotate 270 degrees anticlockwise
530             rotationMatrix_ = detail::RotateMatrix<-270>().postTranslate(static_cast<float>(width_), 0.0);
531             break;
532         }
533         default: {
534             rotationMatrix_ = SkMatrix();
535             break;
536         }
537     };
538 }
539 
GetRotationMatrix() const540 SkMatrix RSScreen::GetRotationMatrix() const
541 {
542     return rotationMatrix_;
543 }
544 
SetRotation(ScreenRotation rotation)545 bool RSScreen::SetRotation(ScreenRotation rotation)
546 {
547     if (rotation_ != rotation) {
548         rotation_ = rotation;
549         UpdateRotationMatrix();
550     }
551 
552     return true;
553 }
554 
GetRotation() const555 ScreenRotation RSScreen::GetRotation() const
556 {
557     return rotation_;
558 }
559 } // namespace impl
560 } // namespace Rosen
561 } // namespace OHOS
562