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