1 /*
2 * Copyright (c) 2022-2023 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 "platform/ohos/overdraw/rs_overdraw_controller.h"
17
18 #include <mutex>
19 #include <sstream>
20
21 #include "hilog/log.h"
22 #include "parameter.h"
23
24 #include "platform/common/rs_log.h"
25
26 namespace OHOS {
27 namespace Rosen {
28 namespace {
29 // param set debug.graphic.overdraw true/false
30 constexpr const char *SWITCH_TEXT = "debug.graphic.overdraw";
31 constexpr const char *SWITCH_ENABLE_TEXT = "true";
32 /* param set debug.graphic.colors_overdraw [color...]
33 * For Example:
34 * param set debug.graphic.colors_overdraw "0 0x220000ff 0x2200ff00 0x22ff0000 0x44ff0000"
35 * means:
36 * - Drawn Once Region: 0x00000000 (transparent)
37 * - Drawn Twice Region: 0x220000ff (alpha: 13% blue)
38 * - Drawn 3 Times Region: 0x2200ff00 (alpha: 13% green)
39 * - Drawn 4 Times Region: 0x22ff0000 (alpha: 13% red)
40 * - Drawn >= 5 Times Region: 0x44ff0000 (alpha: 26% red)
41 */
42 constexpr const char *COLOR_TEXT = "debug.graphic.colors_overdraw";
43 } // namespace
44
GetInstance()45 RSOverdrawController &RSOverdrawController::GetInstance()
46 {
47 static RSOverdrawController instance;
48 return instance;
49 }
50
SetDelegate(const std::shared_ptr<RSDelegate> & delegate)51 void RSOverdrawController::SetDelegate(const std::shared_ptr<RSDelegate> &delegate)
52 {
53 delegate_ = delegate;
54 }
55
IsEnabled() const56 bool RSOverdrawController::IsEnabled() const
57 {
58 return enabled_;
59 }
60
SetEnable(bool enable)61 void RSOverdrawController::SetEnable(bool enable)
62 {
63 if (enabled_ == enable) {
64 return ;
65 }
66 if (enable) {
67 SwitchFunction(SWITCH_TEXT, SWITCH_ENABLE_TEXT, this);
68 } else {
69 SwitchFunction(SWITCH_TEXT, "", this);
70 }
71 }
72
GetColorArray() const73 OverdrawColorArray RSOverdrawController::GetColorArray() const
74 {
75 std::lock_guard lock(colorMutex_);
76 return colorArray_;
77 }
78
79 #ifndef USE_ROSEN_DRAWING
GetColorMap() const80 std::map<int, SkColor> RSOverdrawController::GetColorMap() const
81 #else
82 std::map<int, Drawing::ColorQuad> RSOverdrawController::GetColorMap() const
83 #endif
84 {
85 std::lock_guard lock(colorMutex_);
86 return colorMap_;
87 }
88
RSOverdrawController()89 RSOverdrawController::RSOverdrawController()
90 {
91 char value[0x20];
92 GetParameter(SWITCH_TEXT, "false", value, sizeof(value));
93 SwitchFunction(SWITCH_TEXT, value, this);
94 WatchParameter(SWITCH_TEXT, SwitchFunction, this);
95 WatchParameter(COLOR_TEXT, OnColorChange, this);
96 }
97
SwitchFunction(const char * key,const char * value,void * context)98 void RSOverdrawController::SwitchFunction(const char *key, const char *value, void *context)
99 {
100 auto &that = *reinterpret_cast<RSOverdrawController *>(context);
101 auto oldEnable = that.enabled_;
102 if (strncmp(value, SWITCH_ENABLE_TEXT, strlen(SWITCH_ENABLE_TEXT)) == 0) {
103 that.enabled_ = true;
104 ROSEN_LOGI("%{public}s enable", key);
105 } else {
106 that.enabled_ = false;
107 ROSEN_LOGI("%{public}s disable", key);
108 }
109
110 if (oldEnable != that.enabled_ && that.delegate_ != nullptr) {
111 that.delegate_->Repaint();
112 }
113 }
114
OnColorChange(const char * key,const char * value,void * context)115 void RSOverdrawController::OnColorChange(const char *key, const char *value, void *context)
116 {
117 auto &that = *reinterpret_cast<RSOverdrawController *>(context);
118 std::stringstream ss(value);
119 std::vector<uint32_t> colors;
120 uint32_t color;
121 while (ss >> std::hex >> color) {
122 colors.push_back(color);
123 }
124
125 if (ss.eof() && colors != that.colors_ && colors.size() > 0) {
126 // array
127 OverdrawColorArray colorArray = that.colorArray_;
128 auto colorNumber = colorArray.size();
129 for (size_t i = 0; i < colors.size() && i + 1 < colorNumber; i++) {
130 colorArray[i + 1] = colors[i];
131 }
132 for (size_t i = colors.size(); i + 1 < colorNumber; i++) {
133 colorArray[i + 1] = colors.back();
134 }
135
136 // map
137 #ifndef USE_ROSEN_DRAWING
138 std::map<int, SkColor> colorMap;
139 #else
140 std::map<int, Drawing::ColorQuad> colorMap;
141 #endif
142 for (size_t i = 0; i < colors.size(); i++) {
143 colorMap[i + 1] = colors[i];
144 }
145 colorMap[0] = colors.back();
146
147 {
148 std::lock_guard lock(that.colorMutex_);
149 that.colorArray_ = colorArray;
150 that.colorMap_ = colorMap;
151 }
152
153 if (that.delegate_ != nullptr) {
154 that.delegate_->Repaint();
155 }
156 }
157 }
158 } // namespace Rosen
159 } // namespace OHOS
160