1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Properties.h"
18 #include "Debug.h"
19 
20 #include <algorithm>
21 #include <cstdlib>
22 
23 #include <cutils/compiler.h>
24 #include <cutils/properties.h>
25 #include <log/log.h>
26 
27 namespace android {
28 namespace uirenderer {
29 
30 bool Properties::drawDeferDisabled = false;
31 bool Properties::drawReorderDisabled = false;
32 bool Properties::debugLayersUpdates = false;
33 bool Properties::debugOverdraw = false;
34 bool Properties::showDirtyRegions = false;
35 bool Properties::skipEmptyFrames = true;
36 bool Properties::useBufferAge = true;
37 bool Properties::enablePartialUpdates = true;
38 
39 float Properties::textGamma = DEFAULT_TEXT_GAMMA;
40 
41 int Properties::fboCacheSize = DEFAULT_FBO_CACHE_SIZE;
42 int Properties::gradientCacheSize = MB(DEFAULT_GRADIENT_CACHE_SIZE);
43 int Properties::layerPoolSize = MB(DEFAULT_LAYER_CACHE_SIZE);
44 int Properties::patchCacheSize = KB(DEFAULT_PATCH_CACHE_SIZE);
45 int Properties::pathCacheSize = MB(DEFAULT_PATH_CACHE_SIZE);
46 int Properties::renderBufferCacheSize = MB(DEFAULT_RENDER_BUFFER_CACHE_SIZE);
47 int Properties::tessellationCacheSize = MB(DEFAULT_VERTEX_CACHE_SIZE);
48 int Properties::textDropShadowCacheSize = MB(DEFAULT_DROP_SHADOW_CACHE_SIZE);
49 int Properties::textureCacheSize = MB(DEFAULT_TEXTURE_CACHE_SIZE);
50 
51 float Properties::textureCacheFlushRate = DEFAULT_TEXTURE_CACHE_FLUSH_RATE;
52 
53 DebugLevel Properties::debugLevel = kDebugDisabled;
54 OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
55 StencilClipDebug Properties::debugStencilClip = StencilClipDebug::Hide;
56 
57 float Properties::overrideLightRadius = -1.0f;
58 float Properties::overrideLightPosY = -1.0f;
59 float Properties::overrideLightPosZ = -1.0f;
60 float Properties::overrideAmbientRatio = -1.0f;
61 int Properties::overrideAmbientShadowStrength = -1;
62 int Properties::overrideSpotShadowStrength = -1;
63 
64 ProfileType Properties::sProfileType = ProfileType::None;
65 bool Properties::sDisableProfileBars = false;
66 RenderPipelineType Properties::sRenderPipelineType = RenderPipelineType::NotInitialized;
67 
68 bool Properties::waitForGpuCompletion = false;
69 bool Properties::forceDrawFrame = false;
70 
71 bool Properties::filterOutTestOverhead = false;
72 bool Properties::disableVsync = false;
73 
property_get_int(const char * key,int defaultValue)74 static int property_get_int(const char* key, int defaultValue) {
75     char buf[PROPERTY_VALUE_MAX] = {'\0',};
76 
77     if (property_get(key, buf, "") > 0) {
78         return atoi(buf);
79     }
80     return defaultValue;
81 }
82 
property_get_float(const char * key,float defaultValue)83 static float property_get_float(const char* key, float defaultValue) {
84     char buf[PROPERTY_VALUE_MAX] = {'\0',};
85 
86     if (property_get(key, buf, "") > 0) {
87         return atof(buf);
88     }
89     return defaultValue;
90 }
91 
load()92 bool Properties::load() {
93     char property[PROPERTY_VALUE_MAX];
94     bool prevDebugLayersUpdates = debugLayersUpdates;
95     bool prevDebugOverdraw = debugOverdraw;
96     StencilClipDebug prevDebugStencilClip = debugStencilClip;
97 
98     debugOverdraw = false;
99     if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) {
100         INIT_LOGD("  Overdraw debug enabled: %s", property);
101         if (!strcmp(property, "show")) {
102             debugOverdraw = true;
103             overdrawColorSet = OverdrawColorSet::Default;
104         } else if (!strcmp(property, "show_deuteranomaly")) {
105             debugOverdraw = true;
106             overdrawColorSet = OverdrawColorSet::Deuteranomaly;
107         }
108     }
109 
110     // See Properties.h for valid values
111     if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) {
112         INIT_LOGD("  Stencil clip debug enabled: %s", property);
113         if (!strcmp(property, "hide")) {
114             debugStencilClip = StencilClipDebug::Hide;
115         } else if (!strcmp(property, "highlight")) {
116             debugStencilClip = StencilClipDebug::ShowHighlight;
117         } else if (!strcmp(property, "region")) {
118             debugStencilClip = StencilClipDebug::ShowRegion;
119         }
120     } else {
121         debugStencilClip = StencilClipDebug::Hide;
122     }
123 
124     sProfileType = ProfileType::None;
125     if (property_get(PROPERTY_PROFILE, property, "") > 0) {
126         if (!strcmp(property, PROPERTY_PROFILE_VISUALIZE_BARS)) {
127             sProfileType = ProfileType::Bars;
128         } else if (!strcmp(property, "true")) {
129             sProfileType = ProfileType::Console;
130         }
131     }
132 
133     debugLayersUpdates = property_get_bool(PROPERTY_DEBUG_LAYERS_UPDATES, false);
134     INIT_LOGD("  Layers updates debug enabled: %d", debugLayersUpdates);
135 
136     drawDeferDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_DEFER, false);
137     INIT_LOGD("  Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
138 
139     drawReorderDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_REORDER, false);
140     INIT_LOGD("  Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
141 
142     showDirtyRegions = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
143 
144     debugLevel = (DebugLevel) property_get_int(PROPERTY_DEBUG, kDebugDisabled);
145 
146     skipEmptyFrames = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE, true);
147     useBufferAge = property_get_bool(PROPERTY_USE_BUFFER_AGE, true);
148     enablePartialUpdates = property_get_bool(PROPERTY_ENABLE_PARTIAL_UPDATES, true);
149 
150     textGamma = property_get_float(PROPERTY_TEXT_GAMMA, DEFAULT_TEXT_GAMMA);
151 
152     fboCacheSize = property_get_int(PROPERTY_FBO_CACHE_SIZE, DEFAULT_FBO_CACHE_SIZE);
153     gradientCacheSize = MB(property_get_float(PROPERTY_GRADIENT_CACHE_SIZE, DEFAULT_GRADIENT_CACHE_SIZE));
154     layerPoolSize = MB(property_get_float(PROPERTY_LAYER_CACHE_SIZE, DEFAULT_LAYER_CACHE_SIZE));
155     patchCacheSize = KB(property_get_float(PROPERTY_PATCH_CACHE_SIZE, DEFAULT_PATCH_CACHE_SIZE));
156     pathCacheSize = MB(property_get_float(PROPERTY_PATH_CACHE_SIZE, DEFAULT_PATH_CACHE_SIZE));
157     renderBufferCacheSize = MB(property_get_float(PROPERTY_RENDER_BUFFER_CACHE_SIZE, DEFAULT_RENDER_BUFFER_CACHE_SIZE));
158     tessellationCacheSize = MB(property_get_float(PROPERTY_VERTEX_CACHE_SIZE, DEFAULT_VERTEX_CACHE_SIZE));
159     textDropShadowCacheSize = MB(property_get_float(PROPERTY_DROP_SHADOW_CACHE_SIZE, DEFAULT_DROP_SHADOW_CACHE_SIZE));
160     textureCacheSize = MB(property_get_float(PROPERTY_TEXTURE_CACHE_SIZE, DEFAULT_TEXTURE_CACHE_SIZE));
161     textureCacheFlushRate = std::max(0.0f, std::min(1.0f,
162             property_get_float(PROPERTY_TEXTURE_CACHE_FLUSH_RATE, DEFAULT_TEXTURE_CACHE_FLUSH_RATE)));
163 
164     filterOutTestOverhead = property_get_bool(PROPERTY_FILTER_TEST_OVERHEAD, false);
165 
166     return (prevDebugLayersUpdates != debugLayersUpdates)
167             || (prevDebugOverdraw != debugOverdraw)
168             || (prevDebugStencilClip != debugStencilClip);
169 }
170 
overrideProperty(const char * name,const char * value)171 void Properties::overrideProperty(const char* name, const char* value) {
172     if (!strcmp(name, "disableProfileBars")) {
173         sDisableProfileBars = !strcmp(value, "true");
174         ALOGD("profile bars %s", sDisableProfileBars ? "disabled" : "enabled");
175         return;
176     } else if (!strcmp(name, "ambientRatio")) {
177         overrideAmbientRatio = std::min(std::max(atof(value), 0.0), 10.0);
178         ALOGD("ambientRatio = %.2f", overrideAmbientRatio);
179         return;
180     } else if (!strcmp(name, "lightRadius")) {
181         overrideLightRadius = std::min(std::max(atof(value), 0.0), 3000.0);
182         ALOGD("lightRadius = %.2f", overrideLightRadius);
183         return;
184     } else if (!strcmp(name, "lightPosY")) {
185         overrideLightPosY = std::min(std::max(atof(value), 0.0), 3000.0);
186         ALOGD("lightPos Y = %.2f", overrideLightPosY);
187         return;
188     } else if (!strcmp(name, "lightPosZ")) {
189         overrideLightPosZ = std::min(std::max(atof(value), 0.0), 3000.0);
190         ALOGD("lightPos Z = %.2f", overrideLightPosZ);
191         return;
192     } else if (!strcmp(name, "ambientShadowStrength")) {
193         overrideAmbientShadowStrength = atoi(value);
194         ALOGD("ambient shadow strength = 0x%x out of 0xff", overrideAmbientShadowStrength);
195         return;
196     } else if (!strcmp(name, "spotShadowStrength")) {
197         overrideSpotShadowStrength = atoi(value);
198         ALOGD("spot shadow strength = 0x%x out of 0xff", overrideSpotShadowStrength);
199         return;
200     }
201     ALOGD("failed overriding property %s to %s", name, value);
202 }
203 
getProfileType()204 ProfileType Properties::getProfileType() {
205     if (CC_UNLIKELY(sDisableProfileBars && sProfileType == ProfileType::Bars))
206         return ProfileType::None;
207     return sProfileType;
208 }
209 
getRenderPipelineType()210 RenderPipelineType Properties::getRenderPipelineType() {
211     if (RenderPipelineType::NotInitialized != sRenderPipelineType) {
212         return sRenderPipelineType;
213     }
214     char prop[PROPERTY_VALUE_MAX];
215     property_get(PROPERTY_RENDERER, prop, "opengl");
216     if (!strcmp(prop, "skiagl") ) {
217         ALOGD("Skia GL Pipeline");
218         sRenderPipelineType = RenderPipelineType::SkiaGL;
219     } else if (!strcmp(prop, "skiavk") ) {
220         ALOGD("Skia Vulkan Pipeline");
221         sRenderPipelineType = RenderPipelineType::SkiaVulkan;
222     } else { //"opengl"
223         ALOGD("HWUI GL Pipeline");
224         sRenderPipelineType = RenderPipelineType::OpenGL;
225     }
226     return sRenderPipelineType;
227 }
228 
229 #ifdef HWUI_GLES_WRAP_ENABLED
overrideRenderPipelineType(RenderPipelineType type)230 void Properties::overrideRenderPipelineType(RenderPipelineType type) {
231     sRenderPipelineType = type;
232 }
233 #endif
234 
isSkiaEnabled()235 bool Properties::isSkiaEnabled() {
236     auto renderType = getRenderPipelineType();
237     return RenderPipelineType::SkiaGL == renderType
238             || RenderPipelineType::SkiaVulkan == renderType;
239 }
240 
241 }; // namespace uirenderer
242 }; // namespace android
243