Cleanup properties

bug:19967854

Separate properties from Caches, into static, RenderThread-only class.

Also rewrites the means for java to set properties to correctly handle
threading, and adds an override for profile bars so that SysUi doesn't clutter
the screen with them.

Change-Id: I6e21a96065f52b9ecc49d1a126244804ba106fa9
This commit is contained in:
Chris Craik
2015-05-04 14:36:49 -07:00
parent 57436d3f7e
commit 2507c34d91
26 changed files with 329 additions and 324 deletions

View File

@@ -93,12 +93,6 @@ public class DisplayListCanvas extends Canvas {
private static native long nCreateDisplayListCanvas();
public static void setProperty(String name, String value) {
nSetProperty(name, value);
}
private static native void nSetProperty(String name, String value);
///////////////////////////////////////////////////////////////////////////
// Canvas management
///////////////////////////////////////////////////////////////////////////

View File

@@ -17,6 +17,7 @@
package android.view;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -412,6 +413,13 @@ public class ThreadedRenderer extends HardwareRenderer {
nTrimMemory(level);
}
public static void overrideProperty(@NonNull String name, @NonNull String value) {
if (name == null || value == null) {
throw new IllegalArgumentException("name and value must be non-null");
}
nOverrideProperty(name, value);
}
public static void dumpProfileData(byte[] data, FileDescriptor fd) {
nDumpProfileData(data, fd);
}
@@ -510,6 +518,7 @@ public class ThreadedRenderer extends HardwareRenderer {
private static native void nDestroyHardwareResources(long nativeProxy);
private static native void nTrimMemory(int level);
private static native void nOverrideProperty(String name, String value);
private static native void nFence(long nativeProxy);
private static native void nStopDrawing(long nativeProxy);

View File

@@ -86,24 +86,6 @@ static void android_view_DisplayListCanvas_finish(JNIEnv* env, jobject clazz,
renderer->finish();
}
static void android_view_DisplayListCanvas_setProperty(JNIEnv* env,
jobject clazz, jstring name, jstring value) {
if (!Caches::hasInstance()) {
ALOGW("can't set property, no Caches instance");
return;
}
if (name == NULL || value == NULL) {
ALOGW("can't set prop, null passed");
}
const char* nameCharArray = env->GetStringUTFChars(name, NULL);
const char* valueCharArray = env->GetStringUTFChars(value, NULL);
Caches::getInstance().setTempProperty(nameCharArray, valueCharArray);
env->ReleaseStringUTFChars(name, nameCharArray);
env->ReleaseStringUTFChars(name, valueCharArray);
}
// ----------------------------------------------------------------------------
// Functor
// ----------------------------------------------------------------------------
@@ -268,8 +250,6 @@ static JNINativeMethod gMethods[] = {
{ "nPrepare", "(J)V", (void*) android_view_DisplayListCanvas_prepare },
{ "nPrepareDirty", "(JIIII)V", (void*) android_view_DisplayListCanvas_prepareDirty },
{ "nFinish", "(J)V", (void*) android_view_DisplayListCanvas_finish },
{ "nSetProperty", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) android_view_DisplayListCanvas_setProperty },
{ "nCallDrawGLFunction", "(JJ)V", (void*) android_view_DisplayListCanvas_callDrawGLFunction },

View File

@@ -388,6 +388,15 @@ static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
RenderProxy::trimMemory(level);
}
static void android_view_ThreadedRenderer_overrideProperty(JNIEnv* env, jobject clazz,
jstring name, jstring value) {
const char* nameCharArray = env->GetStringUTFChars(name, NULL);
const char* valueCharArray = env->GetStringUTFChars(value, NULL);
RenderProxy::overrideProperty(nameCharArray, valueCharArray);
env->ReleaseStringUTFChars(name, nameCharArray);
env->ReleaseStringUTFChars(name, valueCharArray);
}
static void android_view_ThreadedRenderer_fence(JNIEnv* env, jobject clazz,
jlong proxyPtr) {
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
@@ -466,6 +475,7 @@ static JNINativeMethod gMethods[] = {
{ "nDetachSurfaceTexture", "(JJ)V", (void*) android_view_ThreadedRenderer_detachSurfaceTexture },
{ "nDestroyHardwareResources", "(J)V", (void*) android_view_ThreadedRenderer_destroyHardwareResources },
{ "nTrimMemory", "(I)V", (void*) android_view_ThreadedRenderer_trimMemory },
{ "nOverrideProperty", "(Ljava/lang/String;Ljava/lang/String;)V", (void*) android_view_ThreadedRenderer_overrideProperty },
{ "nFence", "(J)V", (void*) android_view_ThreadedRenderer_fence },
{ "nStopDrawing", "(J)V", (void*) android_view_ThreadedRenderer_stopDrawing },
{ "nNotifyFramePending", "(J)V", (void*) android_view_ThreadedRenderer_notifyFramePending },

View File

@@ -63,6 +63,7 @@ LOCAL_SRC_FILES := \
PixelBuffer.cpp \
Program.cpp \
ProgramCache.cpp \
Properties.cpp \
RenderBufferCache.cpp \
RenderNode.cpp \
RenderProperties.cpp \

View File

@@ -57,14 +57,8 @@ Caches::Caches(RenderState& renderState)
init();
initFont();
initConstraints();
initProperties();
initStaticProperties();
initExtensions();
initTempProperties();
mDebugLevel = readDebugLevel();
ALOGD_IF(mDebugLevel != kDebugDisabled,
"Enabling debug mode %d", mDebugLevel);
}
bool Caches::init() {
@@ -77,10 +71,6 @@ bool Caches::init() {
mFunctorsCount = 0;
debugLayersUpdates = false;
debugOverdraw = false;
debugStencilClip = kStencilHide;
patchCache.init();
mInitialized = true;
@@ -124,66 +114,6 @@ void Caches::initStaticProperties() {
}
}
bool Caches::initProperties() {
bool prevDebugLayersUpdates = debugLayersUpdates;
bool prevDebugOverdraw = debugOverdraw;
StencilClipDebug prevDebugStencilClip = debugStencilClip;
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_DEBUG_LAYERS_UPDATES, property, nullptr) > 0) {
INIT_LOGD(" Layers updates debug enabled: %s", property);
debugLayersUpdates = !strcmp(property, "true");
} else {
debugLayersUpdates = false;
}
debugOverdraw = false;
if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) {
INIT_LOGD(" Overdraw debug enabled: %s", property);
if (!strcmp(property, "show")) {
debugOverdraw = true;
mOverdrawDebugColorSet = kColorSet_Default;
} else if (!strcmp(property, "show_deuteranomaly")) {
debugOverdraw = true;
mOverdrawDebugColorSet = kColorSet_Deuteranomaly;
}
}
// See Properties.h for valid values
if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) {
INIT_LOGD(" Stencil clip debug enabled: %s", property);
if (!strcmp(property, "hide")) {
debugStencilClip = kStencilHide;
} else if (!strcmp(property, "highlight")) {
debugStencilClip = kStencilShowHighlight;
} else if (!strcmp(property, "region")) {
debugStencilClip = kStencilShowRegion;
}
} else {
debugStencilClip = kStencilHide;
}
if (property_get(PROPERTY_DISABLE_DRAW_DEFER, property, "false")) {
drawDeferDisabled = !strcasecmp(property, "true");
INIT_LOGD(" Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
} else {
drawDeferDisabled = false;
INIT_LOGD(" Draw defer enabled");
}
if (property_get(PROPERTY_DISABLE_DRAW_REORDER, property, "false")) {
drawReorderDisabled = !strcasecmp(property, "true");
INIT_LOGD(" Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
} else {
drawReorderDisabled = false;
INIT_LOGD(" Draw reorder enabled");
}
return (prevDebugLayersUpdates != debugLayersUpdates)
|| (prevDebugOverdraw != debugOverdraw)
|| (prevDebugStencilClip != debugStencilClip);
}
void Caches::terminate() {
if (!mInitialized) return;
mRegionMesh.release();
@@ -231,7 +161,9 @@ uint32_t Caches::getOverdrawColor(uint32_t amount) const {
};
if (amount < 1) amount = 1;
if (amount > 4) amount = 4;
return sOverdrawColors[mOverdrawDebugColorSet][amount - 1];
int overdrawColorIndex = static_cast<int>(Properties::overdrawColorSet);
return sOverdrawColors[overdrawColorIndex][amount - 1];
}
void Caches::dumpMemoryUsage() {
@@ -351,13 +283,13 @@ void Caches::flush(FlushMode mode) {
///////////////////////////////////////////////////////////////////////////////
void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool discard) {
if (mExtensions.hasTiledRendering() && !debugOverdraw) {
if (mExtensions.hasTiledRendering() && !Properties::debugOverdraw) {
glStartTilingQCOM(x, y, width, height, (discard ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM));
}
}
void Caches::endTiling() {
if (mExtensions.hasTiledRendering() && !debugOverdraw) {
if (mExtensions.hasTiledRendering() && !Properties::debugOverdraw) {
glEndTilingQCOM(GL_COLOR_BUFFER_BIT0_QCOM);
}
}
@@ -395,44 +327,5 @@ TextureVertex* Caches::getRegionMesh() {
// Temporary Properties
///////////////////////////////////////////////////////////////////////////////
void Caches::initTempProperties() {
propertyLightRadius = -1.0f;
propertyLightPosY = -1.0f;
propertyLightPosZ = -1.0f;
propertyAmbientRatio = -1.0f;
propertyAmbientShadowStrength = -1;
propertySpotShadowStrength = -1;
}
void Caches::setTempProperty(const char* name, const char* value) {
ALOGD("setting property %s to %s", name, value);
if (!strcmp(name, "ambientRatio")) {
propertyAmbientRatio = fmin(fmax(atof(value), 0.0), 10.0);
ALOGD("ambientRatio = %.2f", propertyAmbientRatio);
return;
} else if (!strcmp(name, "lightRadius")) {
propertyLightRadius = fmin(fmax(atof(value), 0.0), 3000.0);
ALOGD("lightRadius = %.2f", propertyLightRadius);
return;
} else if (!strcmp(name, "lightPosY")) {
propertyLightPosY = fmin(fmax(atof(value), 0.0), 3000.0);
ALOGD("lightPos Y = %.2f", propertyLightPosY);
return;
} else if (!strcmp(name, "lightPosZ")) {
propertyLightPosZ = fmin(fmax(atof(value), 0.0), 3000.0);
ALOGD("lightPos Z = %.2f", propertyLightPosZ);
return;
} else if (!strcmp(name, "ambientShadowStrength")) {
propertyAmbientShadowStrength = atoi(value);
ALOGD("ambient shadow strength = 0x%x out of 0xff", propertyAmbientShadowStrength);
return;
} else if (!strcmp(name, "spotShadowStrength")) {
propertySpotShadowStrength = atoi(value);
ALOGD("spot shadow strength = 0x%x out of 0xff", propertySpotShadowStrength);
return;
}
ALOGD(" failed");
}
}; // namespace uirenderer
}; // namespace android

View File

@@ -80,7 +80,7 @@ public:
}
static bool hasInstance() {
return sInstance != 0;
return sInstance != nullptr;
}
private:
Caches(RenderState& renderState);
@@ -98,11 +98,6 @@ public:
*/
bool init();
/**
* Initialize global system properties.
*/
bool initProperties();
/**
* Flush the cache.
*
@@ -116,14 +111,6 @@ public:
*/
void terminate();
/**
* Indicates whether the renderer is in debug mode.
* This debug mode provides limited information to app developers.
*/
DebugLevel getDebugLevel() const {
return mDebugLevel;
}
/**
* Returns a non-premultiplied ARGB color for the specified
* amount of overdraw (1 for 1x, 2 for 2x, etc.)
@@ -162,22 +149,9 @@ public:
void registerFunctors(uint32_t functorCount);
void unregisterFunctors(uint32_t functorCount);
bool drawDeferDisabled;
bool drawReorderDisabled;
// Misc
GLint maxTextureSize;
// Debugging
bool debugLayersUpdates;
bool debugOverdraw;
enum StencilClipDebug {
kStencilHide,
kStencilShowHighlight,
kStencilShowRegion
};
StencilClipDebug debugStencilClip;
private:
// Declared before gradientCache and programCache which need this to initialize.
// TODO: cleanup / move elsewhere
@@ -207,17 +181,6 @@ public:
PFNGLPUSHGROUPMARKEREXTPROC startMark;
PFNGLPOPGROUPMARKEREXTPROC endMark;
// TEMPORARY properties
void initTempProperties();
void setTempProperty(const char* name, const char* value);
float propertyLightRadius;
float propertyLightPosY;
float propertyLightPosZ;
float propertyAmbientRatio;
int propertyAmbientShadowStrength;
int propertySpotShadowStrength;
void setProgram(const ProgramDescription& description);
void setProgram(Program* program);
@@ -227,10 +190,6 @@ public:
TextureState& textureState() { return *mTextureState; }
private:
enum OverdrawColorSet {
kColorSet_Default = 0,
kColorSet_Deuteranomaly
};
void initFont();
void initExtensions();
@@ -249,13 +208,10 @@ private:
mutable Mutex mGarbageLock;
Vector<Layer*> mLayerGarbage;
DebugLevel mDebugLevel;
bool mInitialized;
uint32_t mFunctorsCount;
OverdrawColorSet mOverdrawDebugColorSet;
// TODO: move below to RenderState
PixelBufferState* mPixelBufferState = nullptr;
TextureState* mTextureState = nullptr;

View File

@@ -28,6 +28,7 @@
#include "DeferredDisplayList.h"
#include "DisplayListOp.h"
#include "OpenGLRenderer.h"
#include "Properties.h"
#include "utils/MathUtils.h"
#if DEBUG_DEFER
@@ -502,7 +503,7 @@ void DeferredDisplayList::addDrawOp(OpenGLRenderer& renderer, DrawOp* op) {
resetBatchingState();
}
if (CC_UNLIKELY(renderer.getCaches().drawReorderDisabled)) {
if (CC_UNLIKELY(Properties::drawReorderDisabled)) {
// TODO: elegant way to reuse batches?
DrawBatch* b = new DrawBatch(deferInfo);
b->add(op, state, deferInfo.opaqueOverBounds);

View File

@@ -18,12 +18,11 @@
#include <cutils/compiler.h>
#include "OpenGLRenderer.h"
#include "Properties.h"
#define DEFAULT_MAX_FRAMES 128
#define RETURN_IF_PROFILING_DISABLED() if (CC_LIKELY(mType == kNone)) return
#define RETURN_IF_DISABLED() if (CC_LIKELY(mType == kNone && !mShowDirtyRegions)) return
#define RETURN_IF_PROFILING_DISABLED() if (CC_LIKELY(mType == ProfileType::None)) return
#define RETURN_IF_DISABLED() if (CC_LIKELY(mType == ProfileType::None && !mShowDirtyRegions)) return
#define NANOS_TO_MILLIS_FLOAT(nanos) ((nanos) * 0.000001f)
@@ -56,18 +55,7 @@ static int dpToPx(int dp, float density) {
return (int) (dp * density + 0.5f);
}
DrawProfiler::DrawProfiler()
: mType(kNone)
, mDensity(0)
, mData(nullptr)
, mDataSize(0)
, mCurrentFrame(-1)
, mPreviousTime(0)
, mVerticalUnit(0)
, mHorizontalUnit(0)
, mThresholdStroke(0)
, mShowDirtyRegions(false)
, mFlashToggle(false) {
DrawProfiler::DrawProfiler() {
setDensity(1);
}
@@ -135,7 +123,7 @@ void DrawProfiler::draw(OpenGLRenderer* canvas) {
}
}
if (mType == kBars) {
if (mType == ProfileType::Bars) {
prepareShapes(canvas->getViewportHeight());
drawGraph(canvas);
drawCurrentFrame(canvas);
@@ -217,32 +205,20 @@ void DrawProfiler::drawThreshold(OpenGLRenderer* canvas) {
canvas->drawLines(pts, 4, &paint);
}
DrawProfiler::ProfileType DrawProfiler::loadRequestedProfileType() {
ProfileType type = kNone;
char buf[PROPERTY_VALUE_MAX] = {'\0',};
if (property_get(PROPERTY_PROFILE, buf, "") > 0) {
if (!strcmp(buf, PROPERTY_PROFILE_VISUALIZE_BARS)) {
type = kBars;
} else if (!strcmp(buf, "true")) {
type = kConsole;
}
}
return type;
}
bool DrawProfiler::loadSystemProperties() {
bool DrawProfiler::consumeProperties() {
bool changed = false;
ProfileType newType = loadRequestedProfileType();
ProfileType newType = Properties::getProfileType();
if (newType != mType) {
mType = newType;
if (mType == kNone) {
if (mType == ProfileType::None) {
destroyData();
} else {
createData();
}
changed = true;
}
bool showDirty = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
bool showDirty = Properties::showDirtyRegions;
if (showDirty != mShowDirtyRegions) {
mShowDirtyRegions = showDirty;
changed = true;

View File

@@ -16,9 +16,11 @@
#ifndef DRAWPROFILER_H
#define DRAWPROFILER_H
#include <utils/Timers.h>
#include "Properties.h"
#include "Rect.h"
#include <utils/Timers.h>
namespace android {
namespace uirenderer {
@@ -29,7 +31,7 @@ public:
DrawProfiler();
~DrawProfiler();
bool loadSystemProperties();
bool consumeProperties();
void setDensity(float density);
void startFrame(nsecs_t recordDurationNanos = 0);
@@ -43,12 +45,6 @@ public:
void dumpData(int fd);
private:
enum ProfileType {
kNone,
kConsole,
kBars,
};
typedef struct {
float record;
float prepare;
@@ -65,20 +61,18 @@ private:
void drawCurrentFrame(OpenGLRenderer* canvas);
void drawThreshold(OpenGLRenderer* canvas);
ProfileType loadRequestedProfileType();
ProfileType mType = ProfileType::None;
float mDensity = 0;
ProfileType mType;
float mDensity;
FrameTimingData* mData = nullptr;
int mDataSize = 0;
FrameTimingData* mData;
int mDataSize;
int mCurrentFrame = -1;
nsecs_t mPreviousTime = 0;
int mCurrentFrame;
nsecs_t mPreviousTime;
int mVerticalUnit;
int mHorizontalUnit;
int mThresholdStroke;
int mVerticalUnit = 0;
int mHorizontalUnit = 0;
int mThresholdStroke = 0;
/*
* mRects represents an array of rect shapes, divided into NUM_ELEMENTS
@@ -87,11 +81,11 @@ private:
* OpenGLRenderer:drawRects() that makes up all the FrameTimingData:record
* information.
*/
float** mRects;
float** mRects = nullptr;
bool mShowDirtyRegions;
bool mShowDirtyRegions = false;
SkRect mDirtyRegion;
bool mFlashToggle;
bool mFlashToggle = false;
};
} /* namespace uirenderer */

View File

@@ -588,8 +588,8 @@ void GlopBuilder::build() {
// Enable debug highlight when what we're about to draw is tested against
// the stencil buffer and if stencil highlight debugging is on
mDescription.hasDebugHighlight = !mCaches.debugOverdraw
&& mCaches.debugStencilClip == Caches::kStencilShowHighlight
mDescription.hasDebugHighlight = !Properties::debugOverdraw
&& Properties::debugStencilClip == StencilClipDebug::ShowHighlight
&& mRenderState.stencil().isTestEnabled();
// serialize shader info into ShaderData

View File

@@ -245,7 +245,7 @@ bool OpenGLRenderer::finish() {
#if DEBUG_MEMORY_USAGE
mCaches.dumpMemoryUsage();
#else
if (mCaches.getDebugLevel() & kDebugMemory) {
if (Properties::debugLevel & kDebugMemory) {
mCaches.dumpMemoryUsage();
}
#endif
@@ -339,7 +339,7 @@ void OpenGLRenderer::debugOverdraw(bool enable, bool clear) {
}
void OpenGLRenderer::renderOverdraw() {
if (mCaches.debugOverdraw && getTargetFbo() == 0) {
if (Properties::debugOverdraw && getTargetFbo() == 0) {
const Rect* clip = &mTilingClip;
mRenderState.scissor().setEnabled(true);
@@ -381,7 +381,7 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
debugOverdraw(false, false);
}
if (CC_UNLIKELY(inFrame || mCaches.drawDeferDisabled)) {
if (CC_UNLIKELY(inFrame || Properties::drawDeferDisabled)) {
layer->render(*this);
} else {
layer->defer(*this);
@@ -392,7 +392,7 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
startTilingCurrentClip();
}
layer->debugDrawUpdate = mCaches.debugLayersUpdates;
layer->debugDrawUpdate = Properties::debugLayersUpdates;
layer->hasDrawnSinceUpdate = false;
return true;
@@ -407,7 +407,7 @@ void OpenGLRenderer::updateLayers() {
// in the layer updates list which will be cleared by flushLayers().
int count = mLayerUpdates.size();
if (count > 0) {
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
startMark("Layer Updates");
} else {
startMark("Defer Layer Updates");
@@ -419,7 +419,7 @@ void OpenGLRenderer::updateLayers() {
updateLayer(layer, false);
}
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
mLayerUpdates.clear();
mRenderState.bindFramebuffer(getTargetFbo());
}
@@ -883,13 +883,13 @@ void OpenGLRenderer::composeLayerRect(Layer* layer, const Rect& rect, bool swap)
* operations are correctly counted twice for overdraw. NOTE: assumes composeLayerRegion only used
* by saveLayer's restore
*/
#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \
DRAW_COMMAND; \
if (CC_UNLIKELY(mCaches.debugOverdraw && getTargetFbo() == 0 && COND)) { \
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \
DRAW_COMMAND; \
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
} \
#define DRAW_DOUBLE_STENCIL_IF(COND, DRAW_COMMAND) { \
DRAW_COMMAND; \
if (CC_UNLIKELY(Properties::debugOverdraw && getTargetFbo() == 0 && COND)) { \
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); \
DRAW_COMMAND; \
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); \
} \
}
#define DRAW_DOUBLE_STENCIL(DRAW_COMMAND) DRAW_DOUBLE_STENCIL_IF(true, DRAW_COMMAND)
@@ -1324,7 +1324,7 @@ void OpenGLRenderer::drawRectangleList(const RectangleList& rectangleList) {
}
void OpenGLRenderer::setStencilFromClip() {
if (!mCaches.debugOverdraw) {
if (!Properties::debugOverdraw) {
if (!currentSnapshot()->clipIsSimple()) {
int incrementThreshold;
EVENT_LOGD("setStencilFromClip - enabling");
@@ -1383,8 +1383,8 @@ void OpenGLRenderer::setStencilFromClip() {
// Draw the region used to generate the stencil if the appropriate debug
// mode is enabled
// TODO: Implement for rectangle list clip areas
if (mCaches.debugStencilClip == Caches::kStencilShowRegion &&
!clipArea.isRectangleList()) {
if (Properties::debugStencilClip == StencilClipDebug::ShowRegion
&& !clipArea.isRectangleList()) {
paint.setColor(0x7f0000ff);
paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
drawRegionRects(currentSnapshot()->getClipRegion(), paint);
@@ -1469,7 +1469,7 @@ void OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t
if (renderNode && renderNode->isRenderable()) {
// compute 3d ordering
renderNode->computeOrdering();
if (CC_UNLIKELY(mCaches.drawDeferDisabled)) {
if (CC_UNLIKELY(Properties::drawDeferDisabled)) {
startFrame();
ReplayStateStruct replayStruct(*this, dirty, replayFlags);
renderNode->replay(replayStruct, 0);
@@ -1478,7 +1478,7 @@ void OpenGLRenderer::drawRenderNode(RenderNode* renderNode, Rect& dirty, int32_t
// Don't avoid overdraw when visualizing, since that makes it harder to
// debug where it's coming from, and when the problem occurs.
bool avoidOverdraw = !mCaches.debugOverdraw;
bool avoidOverdraw = !Properties::debugOverdraw;
DeferredDisplayList deferredList(mState.currentClipRect(), avoidOverdraw);
DeferStateStruct deferStruct(deferredList, *this, replayFlags);
renderNode->defer(deferStruct, 0);
@@ -2452,8 +2452,8 @@ void OpenGLRenderer::drawShadow(float casterAlpha,
// The caller has made sure casterAlpha > 0.
float ambientShadowAlpha = mAmbientShadowAlpha;
if (CC_UNLIKELY(mCaches.propertyAmbientShadowStrength >= 0)) {
ambientShadowAlpha = mCaches.propertyAmbientShadowStrength;
if (CC_UNLIKELY(Properties::overrideAmbientShadowStrength >= 0)) {
ambientShadowAlpha = Properties::overrideAmbientShadowStrength;
}
if (ambientShadowVertexBuffer && ambientShadowAlpha > 0) {
paint.setARGB(casterAlpha * ambientShadowAlpha, 0, 0, 0);
@@ -2461,8 +2461,8 @@ void OpenGLRenderer::drawShadow(float casterAlpha,
}
float spotShadowAlpha = mSpotShadowAlpha;
if (CC_UNLIKELY(mCaches.propertySpotShadowStrength >= 0)) {
spotShadowAlpha = mCaches.propertySpotShadowStrength;
if (CC_UNLIKELY(Properties::overrideSpotShadowStrength >= 0)) {
spotShadowAlpha = Properties::overrideSpotShadowStrength;
}
if (spotShadowVertexBuffer && spotShadowAlpha > 0) {
paint.setARGB(casterAlpha * spotShadowAlpha, 0, 0, 0);

View File

@@ -153,7 +153,7 @@ PathCache::PathCache():
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
mMaxTextureSize = maxTextureSize;
mDebugEnabled = readDebugLevel() & kDebugCaches;
mDebugEnabled = Properties::debugLevel & kDebugCaches;
}
PathCache::~PathCache() {

149
libs/hwui/Properties.cpp Normal file
View File

@@ -0,0 +1,149 @@
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Properties.h"
#include "Debug.h"
#include <cmath>
#include <cutils/log.h>
namespace android {
namespace uirenderer {
bool Properties::drawDeferDisabled = false;
bool Properties::drawReorderDisabled = false;
bool Properties::debugLayersUpdates = false;
bool Properties::debugOverdraw = false;
bool Properties::showDirtyRegions = false;
DebugLevel Properties::debugLevel = kDebugDisabled;
OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
StencilClipDebug Properties::debugStencilClip = StencilClipDebug::Hide;
float Properties::overrideLightRadius = -1.0f;
float Properties::overrideLightPosY = -1.0f;
float Properties::overrideLightPosZ = -1.0f;
float Properties::overrideAmbientRatio = -1.0f;
int Properties::overrideAmbientShadowStrength = -1;
int Properties::overrideSpotShadowStrength = -1;
ProfileType Properties::sProfileType = ProfileType::None;
bool Properties::sDisableProfileBars = false;
bool Properties::load() {
char property[PROPERTY_VALUE_MAX];
bool prevDebugLayersUpdates = debugLayersUpdates;
bool prevDebugOverdraw = debugOverdraw;
StencilClipDebug prevDebugStencilClip = debugStencilClip;
debugOverdraw = false;
if (property_get(PROPERTY_DEBUG_OVERDRAW, property, nullptr) > 0) {
INIT_LOGD(" Overdraw debug enabled: %s", property);
if (!strcmp(property, "show")) {
debugOverdraw = true;
overdrawColorSet = OverdrawColorSet::Default;
} else if (!strcmp(property, "show_deuteranomaly")) {
debugOverdraw = true;
overdrawColorSet = OverdrawColorSet::Deuteranomaly;
}
}
// See Properties.h for valid values
if (property_get(PROPERTY_DEBUG_STENCIL_CLIP, property, nullptr) > 0) {
INIT_LOGD(" Stencil clip debug enabled: %s", property);
if (!strcmp(property, "hide")) {
debugStencilClip = StencilClipDebug::Hide;
} else if (!strcmp(property, "highlight")) {
debugStencilClip = StencilClipDebug::ShowHighlight;
} else if (!strcmp(property, "region")) {
debugStencilClip = StencilClipDebug::ShowRegion;
}
} else {
debugStencilClip = StencilClipDebug::Hide;
}
sProfileType = ProfileType::None;
if (property_get(PROPERTY_PROFILE, property, "") > 0) {
if (!strcmp(property, PROPERTY_PROFILE_VISUALIZE_BARS)) {
sProfileType = ProfileType::Bars;
} else if (!strcmp(property, "true")) {
sProfileType = ProfileType::Console;
}
}
debugLayersUpdates = property_get_bool(PROPERTY_DEBUG_LAYERS_UPDATES, false);
INIT_LOGD(" Layers updates debug enabled: %d", debugLayersUpdates);
drawDeferDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_DEFER, false);
INIT_LOGD(" Draw defer %s", drawDeferDisabled ? "disabled" : "enabled");
drawReorderDisabled = property_get_bool(PROPERTY_DISABLE_DRAW_REORDER, false);
INIT_LOGD(" Draw reorder %s", drawReorderDisabled ? "disabled" : "enabled");
showDirtyRegions = property_get_bool(PROPERTY_DEBUG_SHOW_DIRTY_REGIONS, false);
debugLevel = kDebugDisabled;
if (property_get(PROPERTY_DEBUG, property, nullptr) > 0) {
debugLevel = (DebugLevel) atoi(property);
}
return (prevDebugLayersUpdates != debugLayersUpdates)
|| (prevDebugOverdraw != debugOverdraw)
|| (prevDebugStencilClip != debugStencilClip);
}
void Properties::overrideProperty(const char* name, const char* value) {
if (!strcmp(name, "disableProfileBars")) {
sDisableProfileBars = !strcmp(value, "true");
ALOGD("profile bars %s", sDisableProfileBars ? "disabled" : "enabled");
return;
} else if (!strcmp(name, "ambientRatio")) {
overrideAmbientRatio = fmin(fmax(atof(value), 0.0), 10.0);
ALOGD("ambientRatio = %.2f", overrideAmbientRatio);
return;
} else if (!strcmp(name, "lightRadius")) {
overrideLightRadius = fmin(fmax(atof(value), 0.0), 3000.0);
ALOGD("lightRadius = %.2f", overrideLightRadius);
return;
} else if (!strcmp(name, "lightPosY")) {
overrideLightPosY = fmin(fmax(atof(value), 0.0), 3000.0);
ALOGD("lightPos Y = %.2f", overrideLightPosY);
return;
} else if (!strcmp(name, "lightPosZ")) {
overrideLightPosZ = fmin(fmax(atof(value), 0.0), 3000.0);
ALOGD("lightPos Z = %.2f", overrideLightPosZ);
return;
} else if (!strcmp(name, "ambientShadowStrength")) {
overrideAmbientShadowStrength = atoi(value);
ALOGD("ambient shadow strength = 0x%x out of 0xff", overrideAmbientShadowStrength);
return;
} else if (!strcmp(name, "spotShadowStrength")) {
overrideSpotShadowStrength = atoi(value);
ALOGD("spot shadow strength = 0x%x out of 0xff", overrideSpotShadowStrength);
return;
}
ALOGD("failed overriding property %s to %s", name, value);
}
ProfileType Properties::getProfileType() {
if (CC_UNLIKELY(sDisableProfileBars && sProfileType == ProfileType::Bars))
return ProfileType::None;
return sProfileType;
}
}; // namespace uirenderer
}; // namespace android

View File

@@ -19,12 +19,16 @@
#include <cutils/properties.h>
#include <stdlib.h>
#include <utils/Singleton.h>
/**
* This file contains the list of system properties used to configure
* the OpenGLRenderer.
*/
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
// Compile-time properties
///////////////////////////////////////////////////////////////////////////////
@@ -253,12 +257,61 @@ enum DebugLevel {
// Converts a number of kilo-bytes into bytes
#define KB(s) s * 1024
static inline DebugLevel readDebugLevel() {
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_DEBUG, property, nullptr) > 0) {
return (DebugLevel) atoi(property);
}
return kDebugDisabled;
}
enum class ProfileType {
None,
Console,
Bars
};
enum class OverdrawColorSet {
Default = 0,
Deuteranomaly
};
enum class StencilClipDebug {
Hide,
ShowHighlight,
ShowRegion
};
/**
* Renderthread-only singleton which manages several static rendering properties. Most of these
* are driven by system properties which are queried once at initialization, and again if init()
* is called.
*/
class Properties {
public:
static bool load();
static bool drawDeferDisabled;
static bool drawReorderDisabled;
static bool debugLayersUpdates;
static bool debugOverdraw;
static bool showDirtyRegions;
static DebugLevel debugLevel;
static OverdrawColorSet overdrawColorSet;
static StencilClipDebug debugStencilClip;
// Override the value for a subset of properties in this class
static void overrideProperty(const char* name, const char* value);
static float overrideLightRadius;
static float overrideLightPosY;
static float overrideLightPosZ;
static float overrideAmbientRatio;
static int overrideAmbientShadowStrength;
static int overrideSpotShadowStrength;
static ProfileType getProfileType();
private:
static ProfileType sProfileType;
static bool sDisableProfileBars;
}; // class Caches
}; // namespace uirenderer
}; // namespace android
#endif // ANDROID_HWUI_PROPERTIES_H

View File

@@ -20,11 +20,13 @@
#include <math.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Vector.h>
#include "AmbientShadow.h"
#include "Caches.h"
#include "Properties.h"
#include "ShadowTessellator.h"
#include "SpotShadow.h"
#include "Vector.h"
namespace android {
namespace uirenderer {
@@ -40,9 +42,8 @@ void ShadowTessellator::tessellateAmbientShadow(bool isCasterOpaque,
float heightFactor = 1.0f / 128;
const float geomFactor = 64;
Caches& caches = Caches::getInstance();
if (CC_UNLIKELY(caches.propertyAmbientRatio > 0.0f)) {
heightFactor *= caches.propertyAmbientRatio;
if (CC_UNLIKELY(Properties::overrideAmbientRatio > 0.0f)) {
heightFactor *= Properties::overrideAmbientRatio;
}
Rect ambientShadowBounds(casterBounds);
@@ -66,14 +67,12 @@ void ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
const Rect& casterBounds, const Rect& localClip, VertexBuffer& shadowVertexBuffer) {
ATRACE_CALL();
Caches& caches = Caches::getInstance();
Vector3 adjustedLightCenter(lightCenter);
if (CC_UNLIKELY(caches.propertyLightPosY > 0)) {
adjustedLightCenter.y = - caches.propertyLightPosY; // negated since this shifts up
if (CC_UNLIKELY(Properties::overrideLightPosY > 0)) {
adjustedLightCenter.y = - Properties::overrideLightPosY; // negated since this shifts up
}
if (CC_UNLIKELY(caches.propertyLightPosZ > 0)) {
adjustedLightCenter.z = caches.propertyLightPosZ;
if (CC_UNLIKELY(Properties::overrideLightPosZ > 0)) {
adjustedLightCenter.z = Properties::overrideLightPosZ;
}
#if DEBUG_SHADOW
@@ -87,8 +86,8 @@ void ShadowTessellator::tessellateSpotShadow(bool isCasterOpaque,
reverseReceiverTransform.loadInverse(receiverTransform);
reverseReceiverTransform.mapPoint3d(adjustedLightCenter);
if (CC_UNLIKELY(caches.propertyLightRadius > 0)) {
lightRadius = caches.propertyLightRadius;
if (CC_UNLIKELY(Properties::overrideLightRadius > 0)) {
lightRadius = Properties::overrideLightRadius;
}
// Now light and caster are both in local space, we will check whether

View File

@@ -311,7 +311,7 @@ TessellationCache::TessellationCache()
mCache.setOnEntryRemovedListener(&mBufferRemovedListener);
mShadowCache.setOnEntryRemovedListener(&mBufferPairRemovedListener);
mDebugEnabled = readDebugLevel() & kDebugCaches;
mDebugEnabled = Properties::debugLevel & kDebugCaches;
}
TessellationCache::~TessellationCache() {

View File

@@ -123,7 +123,7 @@ TextDropShadowCache::~TextDropShadowCache() {
void TextDropShadowCache::init() {
mCache.setOnEntryRemovedListener(this);
mDebugEnabled = readDebugLevel() & kDebugMoreCaches;
mDebugEnabled = Properties::debugLevel & kDebugMoreCaches;
}
///////////////////////////////////////////////////////////////////////////////

View File

@@ -66,7 +66,7 @@ TextureCache::TextureCache()
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
INIT_LOGD(" Maximum texture dimension is %d pixels", mMaxTextureSize);
mDebugEnabled = readDebugLevel() & kDebugCaches;
mDebugEnabled = Properties::debugLevel & kDebugCaches;
}
TextureCache::~TextureCache() {

View File

@@ -154,7 +154,7 @@ void RenderState::resumeFromFunctorInvoke() {
}
void RenderState::debugOverdraw(bool enable, bool clear) {
if (mCaches->debugOverdraw && mFramebuffer == 0) {
if (Properties::debugOverdraw && mFramebuffer == 0) {
if (clear) {
scissor().setEnabled(false);
stencil().clear();

View File

@@ -112,9 +112,9 @@ void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) {
CREATE_BRIDGE1(loadSystemProperties, CanvasContext* context) {
bool needsRedraw = false;
if (Caches::hasInstance()) {
needsRedraw = Caches::getInstance().initProperties();
needsRedraw = Properties::load();
}
if (args->context->profiler().loadSystemProperties()) {
if (args->context->profiler().consumeProperties()) {
needsRedraw = true;
}
return (void*) needsRedraw;
@@ -135,7 +135,7 @@ void RenderProxy::setName(const char* name) {
SETUP_TASK(setName);
args->context = mContext;
args->name = name;
postAndWait(task);
postAndWait(task); // block since name/value pointers owned by caller
}
CREATE_BRIDGE2(initialize, CanvasContext* context, ANativeWindow* window) {
@@ -331,7 +331,7 @@ void RenderProxy::destroyHardwareResources() {
post(task);
}
CREATE_BRIDGE2(timMemory, RenderThread* thread, int level) {
CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
CanvasContext::trimMemory(*args->thread, args->level);
return nullptr;
}
@@ -340,13 +340,26 @@ void RenderProxy::trimMemory(int level) {
// Avoid creating a RenderThread to do a trimMemory.
if (RenderThread::hasInstance()) {
RenderThread& thread = RenderThread::getInstance();
SETUP_TASK(timMemory);
SETUP_TASK(trimMemory);
args->thread = &thread;
args->level = level;
thread.queue(task);
}
}
CREATE_BRIDGE2(overrideProperty, const char* name, const char* value) {
Properties::overrideProperty(args->name, args->value);
return nullptr;
}
void RenderProxy::overrideProperty(const char* name, const char* value) {
RenderThread& thread = RenderThread::getInstance();
SETUP_TASK(overrideProperty);
args->name = name;
args->value = value;
staticPostAndWait(task); // expensive, but block here since name/value pointers owned by caller
}
CREATE_BRIDGE0(fence) {
// Intentionally empty
return nullptr;

View File

@@ -90,6 +90,7 @@ public:
ANDROID_API void destroyHardwareResources();
ANDROID_API static void trimMemory(int level);
ANDROID_API static void overrideProperty(const char* name, const char* value);
ANDROID_API void fence();
ANDROID_API void stopDrawing();

View File

@@ -144,6 +144,7 @@ RenderThread::RenderThread() : Thread(true), Singleton<RenderThread>()
, mFrameCallbackTask(nullptr)
, mRenderState(nullptr)
, mEglManager(nullptr) {
Properties::load();
mFrameCallbackTask = new DispatchFrameCallbacks(this);
mLooper = new Looper(false);
run("RenderThread");

View File

@@ -39,7 +39,6 @@ import com.android.systemui.R;
import com.android.systemui.recents.misc.DebugTrigger;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsTaskLoadPlan;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
@@ -392,15 +391,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED);
registerReceiver(mSystemBroadcastReceiver, filter);
// Private API calls to make the shadows look better
try {
Utilities.setShadowProperty("ambientRatio", String.valueOf(1.5f));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
/** Inflates the debug overlay if debug mode is enabled. */

View File

@@ -22,27 +22,11 @@ import android.graphics.Matrix;
import android.graphics.Rect;
import android.view.View;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
/* Common code */
public class Utilities {
// Reflection methods for altering shadows
private static Method sPropertyMethod;
static {
try {
Class<?> c = Class.forName("android.view.DisplayListCanvas");
sPropertyMethod = c.getDeclaredMethod("setProperty", String.class, String.class);
if (!sPropertyMethod.isAccessible()) sPropertyMethod.setAccessible(true);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
/** Scales a rect about its centroid */
public static void scaleRectAboutCenter(Rect r, float scale) {
if (scale != 1.0f) {
@@ -163,12 +147,6 @@ public class Utilities {
(1f - overlayAlpha) * Color.blue(overlayColor)));
}
/** Sets some private shadow properties. */
public static void setShadowProperty(String property, String value)
throws IllegalAccessException, InvocationTargetException {
sPropertyMethod.invoke(null, property, value);
}
/**
* Cancels an animation ensuring that if it has listeners, onCancel and onEnd
* are not called.

View File

@@ -76,6 +76,7 @@ import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ThreadedRenderer;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
@@ -857,6 +858,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
// listen for USER_SETUP_COMPLETE setting (per-user)
resetUserSetupObserver();
// disable profiling bars, since they overlap and clutter the output on app windows
ThreadedRenderer.overrideProperty("disableProfileBars", "true");
// Private API call to make the shadows look better for Recents
ThreadedRenderer.overrideProperty("ambientRatio", String.valueOf(1.5f));
return mStatusBarView;
}