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 
GetColorMap() const79 std::map<int, Drawing::ColorQuad> RSOverdrawController::GetColorMap() const
80 {
81     std::lock_guard lock(colorMutex_);
82     return colorMap_;
83 }
84 
RSOverdrawController()85 RSOverdrawController::RSOverdrawController()
86 {
87     char value[0x20];
88     GetParameter(SWITCH_TEXT, "false", value, sizeof(value));
89     SwitchFunction(SWITCH_TEXT, value, this);
90     WatchParameter(SWITCH_TEXT, SwitchFunction, this);
91     WatchParameter(COLOR_TEXT, OnColorChange, this);
92 }
93 
SwitchFunction(const char * key,const char * value,void * context)94 void RSOverdrawController::SwitchFunction(const char *key, const char *value, void *context)
95 {
96     auto &that = *reinterpret_cast<RSOverdrawController *>(context);
97     auto oldEnable = that.enabled_;
98     if (strncmp(value, SWITCH_ENABLE_TEXT, strlen(SWITCH_ENABLE_TEXT)) == 0) {
99         that.enabled_ = true;
100         ROSEN_LOGI("%{public}s enable", key);
101     } else {
102         that.enabled_ = false;
103         ROSEN_LOGI("%{public}s disable", key);
104     }
105 
106     if (oldEnable != that.enabled_ && that.delegate_ != nullptr) {
107         that.delegate_->Repaint();
108     }
109 }
110 
OnColorChange(const char * key,const char * value,void * context)111 void RSOverdrawController::OnColorChange(const char *key, const char *value, void *context)
112 {
113     auto &that = *reinterpret_cast<RSOverdrawController *>(context);
114     std::stringstream ss(value);
115     std::vector<uint32_t> colors;
116     uint32_t color;
117     while (ss >> std::hex >> color) {
118         colors.push_back(color);
119     }
120 
121     if (ss.eof() && colors != that.colors_ && colors.size() > 0) {
122         // array
123         OverdrawColorArray colorArray = that.colorArray_;
124         auto colorNumber = colorArray.size();
125         for (size_t i = 0; i < colors.size() && i + 1 < colorNumber; i++) {
126             colorArray[i + 1] = colors[i];
127         }
128         for (size_t i = colors.size(); i + 1 < colorNumber; i++) {
129             colorArray[i + 1] = colors.back();
130         }
131 
132         // map
133         std::map<int, Drawing::ColorQuad> colorMap;
134         for (size_t i = 0; i < colors.size(); i++) {
135             colorMap[i + 1] = colors[i];
136         }
137         colorMap[0] = colors.back();
138 
139         {
140             std::lock_guard lock(that.colorMutex_);
141             that.colorArray_ = colorArray;
142             that.colorMap_ = colorMap;
143         }
144 
145         if (that.delegate_ != nullptr) {
146             that.delegate_->Repaint();
147         }
148     }
149 }
150 } // namespace Rosen
151 } // namespace OHOS
152