1 /*
2 * Copyright (c) 2023-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
16 #include "screen_decision_center.h"
17
18 #include "dscreen_constants.h"
19 #include "dscreen_errcode.h"
20 #include "dscreen_log.h"
21
22 namespace OHOS {
23 namespace DistributedHardware {
IsDirtyRectValid(const std::vector<OHOS::Rect> & damages)24 bool ScreenDecisionCenter::IsDirtyRectValid(const std::vector<OHOS::Rect> &damages)
25 {
26 DHLOGI("%{public}s: IsDirtyRectValid.", DSCREEN_LOG_TAG);
27 if (damages.empty()) {
28 DHLOGE("%{public}s: damages size is empty.", DSCREEN_LOG_TAG);
29 return false;
30 }
31 int32_t screenWidth = static_cast<int32_t>(configParam_.GetScreenWidth());
32 int32_t screenHeight = static_cast<int32_t>(configParam_.GetScreenHeight());
33 for (const auto &damage : damages) {
34 if (damage.x < 0 || damage.x > screenWidth || damage.y < 0 ||
35 damage.y > screenHeight || damage.x % TWO == 1 || damage.w % TWO == 1) {
36 DHLOGE("%{public}s: dirty x:%{public}" PRId32 ", y:%{public}" PRId32 ", w:%{public}" PRId32
37 ", h:%{public}" PRId32, DSCREEN_LOG_TAG, damage.x, damage.y, damage.w, damage.h);
38 return false;
39 }
40 int32_t width = screenWidth - damage.x;
41 int32_t height = screenHeight - damage.y;
42 if (damage.w < 0 || damage.w > width || damage.h < 0 || damage.h > height) {
43 DHLOGE("%{public}s: dirty x:%{public}" PRId32 ", y:%{public}" PRId32 ", w:%{public}" PRId32
44 ", h:%{public}" PRId32,
45 DSCREEN_LOG_TAG, damage.x, damage.y, damage.w, damage.h);
46 return false;
47 }
48 }
49 return true;
50 }
51
JudgeDirtyThreshold(const std::vector<OHOS::Rect> & damages)52 bool ScreenDecisionCenter::JudgeDirtyThreshold(const std::vector<OHOS::Rect> &damages)
53 {
54 DHLOGI("%{public}s: JudgeDirtyThreshold.", DSCREEN_LOG_TAG);
55 int32_t allDirtyArea = 0;
56 for (const auto &damage : damages) {
57 allDirtyArea += damage.w * damage.h;
58 if (allDirtyArea > DIRTY_REGION_ARE_THRESHOLD) {
59 DHLOGE("%{public}s: dirtyArea is %{public}" PRId32, DSCREEN_LOG_TAG, allDirtyArea);
60 return false;
61 }
62 }
63 return true;
64 }
65
LimitTime(uint32_t timethreshold)66 bool ScreenDecisionCenter::LimitTime(uint32_t timethreshold)
67 {
68 return difftime(time(nullptr), sendFullTime_) >= timethreshold;
69 }
70
InputBufferImage(sptr<SurfaceBuffer> & surfaceBuffer,const std::vector<OHOS::Rect> & damages)71 int32_t ScreenDecisionCenter::InputBufferImage(sptr<SurfaceBuffer> &surfaceBuffer,
72 const std::vector<OHOS::Rect> &damages)
73 {
74 DHLOGI("%{public}s: InputBufferImage.", DSCREEN_LOG_TAG);
75 if (surfaceBuffer == nullptr) {
76 DHLOGE("%{public}s: surfaceBuffer is null.", DSCREEN_LOG_TAG);
77 return ERR_DH_SCREEN_SURFACE_BUFFER_INVALIED;
78 }
79 if (damages.empty() || frameCount_ < MIN_SURPPORT_FRAME_COUNT ||
80 LimitTime(FORCE_FULL_IMAGE_TIME_INTERAL) ||
81 !IsDirtyRectValid(damages) || !JudgeDirtyThreshold(damages)) {
82 DHLOGI("%{public}s: send full image data.", DSCREEN_LOG_TAG);
83 sendFullTime_ = time(nullptr);
84 int32_t ret = imageProcessor_->ProcessFullImage(surfaceBuffer);
85 if (ret != DH_SUCCESS) {
86 DHLOGE("%{public}s: send full data failed.", DSCREEN_LOG_TAG);
87 return ret;
88 }
89 } else {
90 DHLOGI("%{public}s: send dirty data.", DSCREEN_LOG_TAG);
91 int32_t ret = imageJpeg_->ProcessDamageSurface(surfaceBuffer, damages);
92 if (ret != DH_SUCCESS) {
93 DHLOGE("%{public}s: send dirty data failed.", DSCREEN_LOG_TAG);
94 return ret;
95 }
96 }
97 frameCount_++;
98 return DH_SUCCESS;
99 }
100
ConfigureDecisionCenter(std::shared_ptr<IImageSourceProcessorListener> & listener,std::shared_ptr<IImageSourceProcessor> & imageProcessor)101 int32_t ScreenDecisionCenter::ConfigureDecisionCenter(std::shared_ptr<IImageSourceProcessorListener> &listener,
102 std::shared_ptr<IImageSourceProcessor> &imageProcessor)
103 {
104 DHLOGI("%{public}s: ConfigureDecisionCenter.", DSCREEN_LOG_TAG);
105 if (listener == nullptr || imageProcessor == nullptr) {
106 DHLOGE("%{public}s: Image source process is null.", DSCREEN_LOG_TAG);
107 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
108 }
109 imageJpeg_ = std::make_shared<JpegImageProcessor>(configParam_);
110 imageJpeg_->SetImageProcessListener(listener);
111 imageProcessor_ = imageProcessor;
112 return DH_SUCCESS;
113 }
114
SetJpegSurface(sptr<Surface> & surface)115 int32_t ScreenDecisionCenter::SetJpegSurface(sptr<Surface> &surface)
116 {
117 DHLOGI("%{public}s: SetJpegSurface.", DSCREEN_LOG_TAG);
118 if (surface == nullptr) {
119 DHLOGE("%{public}s: Jpeg source is null.", DSCREEN_LOG_TAG);
120 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
121 }
122 return imageJpeg_->SetOutputSurface(surface);
123 }
124 } // namespace DistributedHardware
125 } // namespace OHOS