• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025-2025 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 "screen_pointer.h"
16 
17 #include "bytrace_adapter.h"
18 #include "define_multimodal.h"
19 #include "transaction/rs_transaction.h"
20 #include "transaction/rs_interfaces.h"
21 #include "product_type_parser.h"
22 #include "product_name_definition.h"
23 
24 #undef MMI_LOG_DOMAIN
25 #define MMI_LOG_DOMAIN MMI_LOG_CURSOR
26 #undef MMI_LOG_TAG
27 #define MMI_LOG_TAG "ScreenPointer"
28 
29 namespace OHOS::MMI {
30 const char* RS_SURFACE_NODE_NAME{"pointer window"};
31 const char* POINTER_SIZE{"pointerSize"};
32 constexpr int32_t RS_NODE_CANVAS_INDEX{-1};
33 constexpr int32_t DEFAULT_POINTER_SIZE{1};
34 constexpr int32_t DEVICE_INDEPENDENT_PIXELS{40};
35 constexpr int32_t BASELINE_DENSITY{160};
36 constexpr int32_t POINTER_WINDOW_INIT_SIZE{64};
37 constexpr int32_t BUFFER_RELEASE_WAIT_MS{1000};
38 constexpr int32_t NUM_TWO{2};
39 constexpr int32_t DEFAULT_BUFFER_SIZE{10};
40 constexpr int32_t DEFAULT_CURSOR_SIZE{512};
41 constexpr uint32_t FOCUS_POINT = DEFAULT_CURSOR_SIZE / NUM_TWO;
42 constexpr int32_t BUFFER_TIMEOUT{150};
43 constexpr int32_t STRIDE_ALIGNMENT{8};
44 constexpr uint32_t RENDER_STRIDE{4};
45 constexpr uint32_t POINTER_SIZE_DEFAULT { 1 };
46 constexpr uint32_t POINTER_SIZE_FOLD_PC { 2 };
47 constexpr int32_t ANGLE_90 { 90 };
48 constexpr int32_t ANGLE_360 { 360 };
49 
50 
GetScreenInfoWidth(screen_info_ptr_t si)51 uint32_t GetScreenInfoWidth(screen_info_ptr_t si)
52 {
53     uint32_t width = 0;
54     auto modeId = si->GetModeId();
55     auto modes = si->GetModes();
56     if (modeId < 0 || modeId >= modes.size()) {
57         return 0;
58     }
59     return modes[modeId]->width_;
60 }
GetScreenInfoHeight(screen_info_ptr_t si)61 uint32_t GetScreenInfoHeight(screen_info_ptr_t si)
62 {
63     uint32_t height = 0;
64     auto modeId = si->GetModeId();
65     auto modes = si->GetModes();
66     if (modeId < 0 || modeId >= modes.size()) {
67         return 0;
68     }
69     return modes[modeId]->height_;
70 }
71 
ScreenPointer(hwcmgr_ptr_t hwcMgr,handler_ptr_t handler,const OLD::DisplayInfo & di)72 ScreenPointer::ScreenPointer(hwcmgr_ptr_t hwcMgr, handler_ptr_t handler, const OLD::DisplayInfo &di)
73     : hwcMgr_(hwcMgr), handler_(handler)
74 {
75     screenId_ = di.rsId;
76     width_ = di.width;
77     height_ = di.height;
78     rotation_ = static_cast<rotation_t>(di.direction);
79     if (rotation_ == rotation_t::ROTATION_90 ||
80         rotation_ == rotation_t::ROTATION_270) {
81         std::swap(width_, height_);
82     }
83     dpi_ = float(di.dpi) / BASELINE_DENSITY;
84     MMI_HILOGI("Construct with DisplayInfo, id=%{public}" PRIu64 ", shape=(%{public}u, %{public}u), mode=%{public}u, "
85         "rotation=%{public}u, dpi=%{public}f", screenId_, width_, height_, mode_, rotation_, dpi_);
86 }
87 
ScreenPointer(hwcmgr_ptr_t hwcMgr,handler_ptr_t handler,screen_info_ptr_t si)88 ScreenPointer::ScreenPointer(hwcmgr_ptr_t hwcMgr, handler_ptr_t handler, screen_info_ptr_t si)
89     : hwcMgr_(hwcMgr), handler_(handler)
90 {
91     screenId_ = si->GetRsId();
92     width_ = GetScreenInfoWidth(si);
93     height_ = GetScreenInfoHeight(si);
94     mode_ = si->GetSourceMode();
95     rotation_ = si->GetRotation();
96     dpi_ = si->GetVirtualPixelRatio();
97     MMI_HILOGI("Construct with ScreenInfo, id=%{public}" PRIu64 ", shape=(%{public}u, %{public}u), mode=%{public}u, "
98         "rotation=%{public}u, dpi=%{public}f", screenId_, width_, height_, mode_, rotation_, dpi_);
99 }
100 
Init(PointerRenderer & render)101 bool ScreenPointer::Init(PointerRenderer &render)
102 {
103     if (!InitSurface()) {
104         MMI_HILOGE("ScreenPointer InitSurface failed");
105         return false;
106     }
107 
108     RenderConfig defaultCursorCfg {
109         .style_ = MOUSE_ICON::DEFAULT,
110         .align_ = ICON_TYPE::ANGLE_NW,
111         .path_ = "/system/etc/multimodalinput/mouse_icon/Default.svg",
112         .color = 0,
113         .size = POINTER_SIZE_DEFAULT,
114         .direction = Direction::DIRECTION0,
115         .dpi = this->GetDPI() * this->GetScale(),
116         .isHard = true,
117     };
118     if (OHOS::system::GetParameter("const.build.product", "HYM") == DEVICE_TYPE_FOLD_PC) {
119         defaultCursorCfg.size = POINTER_SIZE_FOLD_PC;
120     }
121     defaultCursorCfg_ = defaultCursorCfg;
122 
123     // Init buffers
124     OHOS::BufferRequestConfig bufferCfg = {
125         .width = DEFAULT_CURSOR_SIZE,
126         .height = DEFAULT_CURSOR_SIZE,
127         .strideAlignment = STRIDE_ALIGNMENT,
128         .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
129         .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA | BUFFER_USAGE_HW_COMPOSER
130             | BUFFER_USAGE_MEM_MMZ_CACHE,
131         .timeout = BUFFER_TIMEOUT,
132     };
133     if (!InitDefaultBuffer(bufferCfg, render)) {
134         MMI_HILOGE("ScreenPointer InitDefaultBuffer failed");
135         return false;
136     }
137     if (!InitTransparentBuffer(bufferCfg)) {
138         MMI_HILOGE("ScreenPointer InitTransparentBuffer failed");
139         return false;
140     }
141     if (!InitCommonBuffer(bufferCfg)) {
142         MMI_HILOGE("ScreenPointer InitCommonBuffer failed");
143         return false;
144     }
145     currentBuffer_ = GetCommonBuffer();
146     return true;
147 }
148 
InitDefaultBuffer(const OHOS::BufferRequestConfig & bufferCfg,PointerRenderer & render)149 bool ScreenPointer::InitDefaultBuffer(const OHOS::BufferRequestConfig &bufferCfg, PointerRenderer &render)
150 {
151     buffer_ptr_t buffer = CreateSurfaceBuffer(bufferCfg);
152     CHKPF(buffer);
153     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
154     CHKPF(addr);
155     int32_t ret = render.Render(addr, buffer->GetWidth(), buffer->GetHeight(), defaultCursorCfg_);
156     if (ret != RET_OK) {
157         MMI_HILOGE("Render failed, ret:%{public}d.", ret);
158         defaultBuffer_ = nullptr;
159         return false;
160     }
161     defaultBuffer_ = buffer;
162     return true;
163 }
164 
InitTransparentBuffer(const OHOS::BufferRequestConfig & bufferCfg)165 bool ScreenPointer::InitTransparentBuffer(const OHOS::BufferRequestConfig &bufferCfg)
166 {
167     buffer_ptr_t buffer = CreateSurfaceBuffer(bufferCfg);
168     CHKPF(buffer);
169     auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
170     CHKPF(addr);
171 
172     uint32_t addrSize = static_cast<uint32_t>(buffer->GetWidth() * buffer->GetHeight()) * RENDER_STRIDE;
173     (void)memset_s(addr, addrSize, 0, addrSize);
174     transparentBuffer_ = buffer;
175     return true;
176 }
177 
InitCommonBuffer(const OHOS::BufferRequestConfig & bufferCfg)178 bool ScreenPointer::InitCommonBuffer(const OHOS::BufferRequestConfig &bufferCfg)
179 {
180     for (int32_t i = 0; (i < DEFAULT_BUFFER_SIZE) && (commonBuffers_.size() < DEFAULT_BUFFER_SIZE); i++) {
181         buffer_ptr_t buffer = CreateSurfaceBuffer(bufferCfg);
182         CHKPF(buffer);
183         commonBuffers_.push_back(buffer);
184     }
185     return true;
186 }
187 
GetDefaultBuffer()188 buffer_ptr_t ScreenPointer::GetDefaultBuffer()
189 {
190     currentBuffer_ = defaultBuffer_;
191     return defaultBuffer_;
192 }
193 
GetTransparentBuffer()194 buffer_ptr_t ScreenPointer::GetTransparentBuffer()
195 {
196     currentBuffer_ = transparentBuffer_;
197     return transparentBuffer_;
198 }
199 
GetCommonBuffer()200 buffer_ptr_t ScreenPointer::GetCommonBuffer()
201 {
202     uint32_t bufferSize = static_cast<uint32_t>(commonBuffers_.size());
203     if (bufferSize != DEFAULT_BUFFER_SIZE) {
204         MMI_HILOGE("The buffer size is incorrect, size:%{public}u", bufferSize);
205         return nullptr;
206     }
207 
208     bufferId_++;
209     bufferId_ %= bufferSize;
210     currentBuffer_ = commonBuffers_[bufferId_];
211     return commonBuffers_[bufferId_];
212 }
213 
RequestBuffer(const RenderConfig & cfg,bool & isCommonBuffer)214 buffer_ptr_t ScreenPointer::RequestBuffer(const RenderConfig &cfg, bool &isCommonBuffer)
215 {
216     if (cfg.style_ == MOUSE_ICON::TRANSPARENT_ICON) {
217         MMI_HILOGD("The buffer transparent buffer.");
218         isCommonBuffer = false;
219         return GetTransparentBuffer();
220     } else if (IsDefaultCfg(cfg)) {
221         MMI_HILOGD("The buffer default buffer.");
222         isCommonBuffer = false;
223         return GetDefaultBuffer();
224     }
225     isCommonBuffer = true;
226     return GetCommonBuffer();
227 }
228 
IsDefaultCfg(const RenderConfig & cfg)229 bool ScreenPointer::IsDefaultCfg(const RenderConfig &cfg)
230 {
231     return (cfg == defaultCursorCfg_) && (cfg.direction == defaultCursorCfg_.direction)
232         && (cfg.align_ == defaultCursorCfg_.align_) && (cfg.isHard == defaultCursorCfg_.isHard);
233 }
234 
GetCurrentBuffer()235 buffer_ptr_t ScreenPointer::GetCurrentBuffer()
236 {
237     return currentBuffer_;
238 }
239 
CreateSurfaceBuffer(const OHOS::BufferRequestConfig & bufferCfg)240 buffer_ptr_t ScreenPointer::CreateSurfaceBuffer(const OHOS::BufferRequestConfig &bufferCfg)
241 {
242     buffer_ptr_t buffer = OHOS::SurfaceBuffer::Create();
243     if (buffer == nullptr) {
244         MMI_HILOGE("SurfaceBuffer Create failed");
245         return nullptr;
246     }
247     OHOS::GSError ret = buffer->Alloc(bufferCfg);
248     if (ret != OHOS::GSERROR_OK) {
249         MMI_HILOGE("SurfaceBuffer Alloc failed, %{public}s", GSErrorStr(ret).c_str());
250         return nullptr;
251     }
252     return buffer;
253 }
254 
InitSurface()255 bool ScreenPointer::InitSurface()
256 {
257     // create SurfaceNode
258     Rosen::RSSurfaceNodeConfig surfaceNodeConfig;
259     surfaceNodeConfig.SurfaceNodeName = RS_SURFACE_NODE_NAME;
260     surfaceNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, Rosen::RSSurfaceNodeType::CURSOR_NODE);
261     CHKPF(surfaceNode_);
262     MMI_HILOGI("SurfaceNode::Create success");
263 
264     // set soft cursor buffer size
265     auto surface = surfaceNode_->GetSurface();
266     CHKPF(surface);
267     surface->SetQueueSize(DEFAULT_BUFFER_SIZE);
268 
269     surfaceNode_->SetVisible(true);
270     surfaceNode_->SetFrameGravity(Rosen::Gravity::TOP_LEFT);
271     surfaceNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
272     surfaceNode_->AttachToDisplay(screenId_);
273     surfaceNode_->SetBounds(0, 0, DEFAULT_CURSOR_SIZE, DEFAULT_CURSOR_SIZE);
274     MMI_HILOGI("AttachToDisplay %{public}" PRIu64 " completed", screenId_);
275 
276     // create canvas node
277     canvasNode_ = Rosen::RSCanvasNode::Create();
278     CHKPF(canvasNode_);
279     canvasNode_->SetBounds(0, 0, DEFAULT_CURSOR_SIZE, DEFAULT_CURSOR_SIZE);
280     canvasNode_->SetFrame(0, 0, DEFAULT_CURSOR_SIZE, DEFAULT_CURSOR_SIZE);
281 #ifndef USE_ROSEN_DRAWING
282     canvasNode_->SetBackgroundColor(SK_ColorTRANSPARENT);
283 #else
284     canvasNode_->SetBackgroundColor(Rosen::Drawing::Color::COLOR_TRANSPARENT);
285 #endif // USE_ROSEN_DRAWING
286 
287     canvasNode_->SetCornerRadius(1);
288     canvasNode_->SetPositionZ(Rosen::RSSurfaceNode::POINTER_WINDOW_POSITION_Z);
289     canvasNode_->SetRotation(float(rotation_));
290     surfaceNode_->AddChild(canvasNode_, RS_NODE_CANVAS_INDEX);
291 
292     MMI_HILOGI("InitSurface completed");
293     return true;
294 }
295 
UpdateScreenInfo(const sptr<OHOS::Rosen::ScreenInfo> si)296 void ScreenPointer::UpdateScreenInfo(const sptr<OHOS::Rosen::ScreenInfo> si)
297 {
298     CHKPV(si);
299     auto id = si->GetRsId();
300     if (screenId_ != id) {
301         CHKPV(surfaceNode_);
302         surfaceNode_->AttachToDisplay(id);
303         Rosen::RSTransaction::FlushImplicitTransaction();
304     }
305 
306     screenId_ = si->GetRsId();
307     width_ = GetScreenInfoWidth(si);
308     height_ = GetScreenInfoHeight(si);
309     mode_ = si->GetSourceMode();
310     rotation_ = si->GetRotation();
311     dpi_ = si->GetVirtualPixelRatio();
312     surfaceNode_->AttachToDisplay(screenId_);
313     Rosen::RSTransaction::FlushImplicitTransaction();
314     MMI_HILOGI("Update with ScreenInfo, id=%{public}" PRIu64 ", shape=(%{public}u, %{public}u), mode=%{public}u, "
315         "rotation=%{public}u, dpi=%{public}f", screenId_, width_, height_, mode_, rotation_, dpi_);
316 }
317 
OnDisplayInfo(const OLD::DisplayInfo & di,bool isWindowRotation)318 void ScreenPointer::OnDisplayInfo(const OLD::DisplayInfo &di, bool isWindowRotation)
319 {
320     if (screenId_ != di.rsId) {
321         return;
322     }
323 
324     isCurrentOffScreenRendering_ = di.isCurrentOffScreenRendering;
325     dpi_ = float(di.dpi) / BASELINE_DENSITY;
326     if (!IsMirror()) {
327         rotation_ = static_cast<rotation_t>(di.direction);
328     }
329     displayDirection_ = di.displayDirection;
330     isWindowRotation_ = isWindowRotation;
331     MMI_HILOGD("Update with DisplayInfo, id=%{public}" PRIu64 ", shape=(%{public}u, %{public}u), mode=%{public}u, "
332         "rotation=%{public}u, dpi=%{public}f", screenId_, width_, height_, mode_, rotation_, dpi_);
333     if (isCurrentOffScreenRendering_) {
334         screenRealDPI_ = di.screenRealDPI;
335         if (di.width == 0) {
336             MMI_HILOGE("The divisor cannot be 0");
337             return;
338         }
339         offRenderScale_ = float(di.screenRealWidth) / di.width;
340         MMI_HILOGD("Update with DisplayInfo, screenRealDPI=%{public}d, offRenderScale_=(%{public}f ",
341             screenRealDPI_, offRenderScale_);
342     }
343 }
344 
UpdatePadding(uint32_t mainWidth,uint32_t mainHeight)345 bool ScreenPointer::UpdatePadding(uint32_t mainWidth, uint32_t mainHeight)
346 {
347     if (!IsMirror()) {
348         MMI_HILOGI("UpdatePadidng, reset padding, screenId=%{public}" PRIu64 ", scale=%{public}f, "
349             "paddingTop_=%{public}u, paddingLeft_=%{public}u", screenId_, scale_, paddingTop_, paddingLeft_);
350         scale_ = 1.0;
351         paddingTop_ = 0;
352         paddingLeft_ = 0;
353         return false;
354     }
355     if (mainWidth == 0 || mainHeight == 0) {
356         MMI_HILOGE("Invalid parameters, mainWidth=%{public}u, mainHeight=%{public}u", mainWidth, mainHeight);
357         return false;
358     }
359     if (rotation_ == rotation_t::ROTATION_90 || rotation_ == rotation_t::ROTATION_270) {
360         std::swap(mainWidth, mainHeight);
361     }
362 
363     // caculate padding for mirror screens
364     scale_ = fmin(float(width_) / mainWidth, float(height_) / mainHeight);
365     paddingTop_ = (height_ - mainHeight * scale_) / NUM_TWO;
366     paddingLeft_ = (width_ - mainWidth * scale_) / NUM_TWO;
367     MMI_HILOGI("UpdatePadding, screenId=%{public}" PRIu64 ", scale=%{public}f, paddingTop_=%{public}u,"
368                " paddingLeft_=%{public}u", screenId_, scale_, paddingTop_, paddingLeft_);
369     return true;
370 }
371 
Rotate(rotation_t rotation,int32_t & x,int32_t & y)372 void ScreenPointer::Rotate(rotation_t rotation, int32_t& x, int32_t& y)
373 {
374     // 坐标轴绕原点旋转 再平移
375     int32_t tmpX = x;
376     int32_t tmpY = y;
377     int32_t width = static_cast<int32_t>(width_);
378     int32_t height = static_cast<int32_t>(height_);
379     if (IsMirror()) {
380         height -= paddingTop_ * NUM_TWO;
381         width -= paddingLeft_ * NUM_TWO;
382     }
383     // 主屏旋转 坐标系会一起旋转,但镜像屏此时坐标系不旋转
384     if (IsMirror() && (rotation_ == rotation_t::ROTATION_90 || rotation_ == rotation_t::ROTATION_270)) {
385         std::swap(width, height);
386     }
387     if ((IsMain() || IsMirror()) && isWindowRotation_ &&
388         (displayDirection_ == DIRECTION90 || displayDirection_ == DIRECTION270)) {
389         std::swap(width, height);
390     }
391 
392     if (rotation == rotation_t(DIRECTION90)) {
393         x = height - tmpY;
394         y = tmpX;
395     } else if (rotation == rotation_t(DIRECTION180)) {
396         x = width - tmpX;
397         y = height - tmpY;
398     } else if (rotation == rotation_t(DIRECTION270)) {
399         x = tmpY;
400         y = width - tmpX;
401     }
402 }
403 
CalculateHwcPositionForMirror(int32_t & x,int32_t & y)404 void ScreenPointer::CalculateHwcPositionForMirror(int32_t& x, int32_t& y)
405 {
406     x = x * scale_;
407     y = y * scale_;
408     Direction direction = DIRECTION0;
409     if (isWindowRotation_) {
410         direction = static_cast<Direction>((((static_cast<Direction>(rotation_) - displayDirection_) *
411             ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
412     } else {
413         direction = static_cast<Direction>(rotation_);
414     }
415     Rotate(rotation_t(direction), x, y);
416 
417     x += paddingLeft_;
418     y += paddingTop_;
419 }
420 
CalculateHwcPositionForExtend(int32_t & x,int32_t & y)421 void ScreenPointer::CalculateHwcPositionForExtend(int32_t& x, int32_t& y)
422 {
423     x = x * offRenderScale_;
424     y = y * offRenderScale_;
425 }
426 
Move(int32_t x,int32_t y,ICON_TYPE align)427 bool ScreenPointer::Move(int32_t x, int32_t y, ICON_TYPE align)
428 {
429     if (isVirtualExtend_) {
430         MMI_HILOGD("Virtual extend screen move, screenId=%{public}" PRIu64, screenId_);
431         return true;
432     }
433     CHKPF(hwcMgr_);
434     int32_t px = 0;
435     int32_t py = 0;
436     if (IsMirror()) {
437         CalculateHwcPositionForMirror(x, y);
438     } else if (GetIsCurrentOffScreenRendering() && !IsMirror()) {
439         CalculateHwcPositionForExtend(x, y);
440     }
441     if (IsMain() && isWindowRotation_) {
442         Direction direction = static_cast<Direction>((((DIRECTION0 - displayDirection_) *
443             ANGLE_90 + ANGLE_360) % ANGLE_360) / ANGLE_90);
444         Rotate(rotation_t(direction), x, y);
445     }
446     if (IsPositionOutScreen(x, y)) {
447         MMI_HILOGE("Position out of screen");
448     }
449     px = x - FOCUS_POINT;
450     py = y - FOCUS_POINT;
451 
452     auto buffer = GetCurrentBuffer();
453     CHKPF(buffer);
454     auto bh = buffer->GetBufferHandle();
455     CHKPF(bh);
456     BytraceAdapter::StartHardPointerMove(buffer->GetWidth(), buffer->GetHeight(), bufferId_, screenId_);
457     auto ret = hwcMgr_->SetPosition(screenId_, px, py, bh);
458     BytraceAdapter::StopHardPointerMove();
459     if (ret != RET_OK) {
460         MMI_HILOGE("SetPosition failed, screenId=%{public}" PRIu64 ", pos=(%{private}d, %{private}d)",
461             screenId_, px, py);
462         return false;
463     }
464     return true;
465 }
466 
MoveSoft(int32_t x,int32_t y,ICON_TYPE align)467 bool ScreenPointer::MoveSoft(int32_t x, int32_t y, ICON_TYPE align)
468 {
469     CHKPF(surfaceNode_);
470     int32_t px = 0;
471     int32_t py = 0;
472     if (IsMirror()) {
473         CalculateHwcPositionForMirror(x, y);
474     } else if (!IsExtend() && !isWindowRotation_) {
475         Rotate(rotation_, x, y);
476     }
477     px = x - FOCUS_POINT;
478     py = y - FOCUS_POINT;
479 
480     if (!IsMirror()) {
481         int64_t nodeId = surfaceNode_->GetId();
482         Rosen::RSInterfaces::GetInstance().SetHwcNodeBounds(nodeId, px, py, DEFAULT_CURSOR_SIZE, DEFAULT_CURSOR_SIZE);
483     } else {
484         surfaceNode_->SetBounds(px, py, DEFAULT_CURSOR_SIZE, DEFAULT_CURSOR_SIZE);
485     }
486 
487     return true;
488 }
489 
SetInvisible()490 bool ScreenPointer::SetInvisible()
491 {
492     if (isVirtualExtend_) {
493         MMI_HILOGD("Virtual extend screen set invisible, screenId=%{public}" PRIu64, screenId_);
494         return true;
495     }
496     CHKPF(hwcMgr_);
497 
498     auto buffer = GetTransparentBuffer();
499     CHKPF(buffer);
500     int32_t width = buffer->GetWidth();
501     int32_t height = buffer->GetHeight();
502     if ((width < 0) || (height < 0)) {
503         MMI_HILOGI("The input data is incorrect, width:%{public}d, height:%{public}d.", width, height);
504         return false;
505     }
506     auto sret = buffer->FlushCache();
507     if (sret != RET_OK) {
508         MMI_HILOGE("FlushCache ret: %{public}d", sret);
509         return sret;
510     }
511 
512     auto bh = buffer->GetBufferHandle();
513     CHKPF(bh);
514     auto ret = hwcMgr_->SetPosition(screenId_, 0, 0, bh);
515     if (ret != RET_OK) {
516         MMI_HILOGE("SetLocation failed, screenId=%{public}" PRIu64 ", loc=(%{private}d, %{private}d)", screenId_, 0, 0);
517         return false;
518     }
519     MMI_HILOGI("SetInvisible success, screenId=%{public}" PRIu64, screenId_);
520     return true;
521 }
522 
GetRenderDPI() const523 float ScreenPointer::GetRenderDPI() const
524 {
525     if (GetIsCurrentOffScreenRendering() && !IsMirror()) {
526         return float(GetScreenRealDPI()) / BASELINE_DENSITY;
527     } else {
528         return dpi_ * scale_;
529     }
530 }
531 
IsPositionOutScreen(int32_t x,int32_t y)532 bool ScreenPointer::IsPositionOutScreen(int32_t x, int32_t y)
533 {
534     int32_t width = static_cast<int32_t>(width_);
535     int32_t height = static_cast<int32_t>(height_);
536     if (x < 0 || y < 0 || x > width || y > height) {
537         MMI_HILOGE("Position out of screen, x=%{private}d, y=%{private}d, width=%{public}d, height=%{public}d",
538             x, y, width, height);
539         return true;
540     }
541     return false;
542 }
543 
544 } // namespace OHOS::MMI