Skip to content

Commit 7c450aa

Browse files
author
Romain Guy
committed
Add support for a new developer setting: overdraw debugging
Change-Id: I350ba4486577c3289f82c20938f7a35138778727
1 parent f7e52d9 commit 7c450aa

File tree

8 files changed

+116
-7
lines changed

8 files changed

+116
-7
lines changed

core/java/android/view/HardwareRenderer.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,17 @@ public abstract class HardwareRenderer {
148148
public static final String DEBUG_SHOW_LAYERS_UPDATES_PROPERTY =
149149
"debug.hwui.show_layers_updates";
150150

151+
/**
152+
* Turn on to show overdraw level.
153+
*
154+
* Possible values:
155+
* "true", to enable overdraw debugging
156+
* "false", to disable overdraw debugging
157+
*
158+
* @hide
159+
*/
160+
public static final String DEBUG_SHOW_OVERDRAW_PROPERTY = "debug.hwui.show_overdraw";
161+
151162
/**
152163
* A process can set this flag to false to prevent the use of hardware
153164
* rendering.
@@ -649,6 +660,7 @@ static abstract class GlRenderer extends HardwareRenderer {
649660
int mProfileCurrentFrame = -PROFILE_FRAME_DATA_COUNT;
650661

651662
final boolean mDebugDirtyRegions;
663+
final boolean mShowOverdraw;
652664

653665
final int mGlVersion;
654666
final boolean mTranslucent;
@@ -698,6 +710,9 @@ static abstract class GlRenderer extends HardwareRenderer {
698710
if (mDebugDirtyRegions) {
699711
Log.d(LOG_TAG, "Debugging dirty regions");
700712
}
713+
714+
mShowOverdraw = SystemProperties.getBoolean(
715+
HardwareRenderer.DEBUG_SHOW_OVERDRAW_PROPERTY, false);
701716
}
702717

703718
@Override
@@ -1414,7 +1429,8 @@ int[] getConfig(boolean dirtyRegions) {
14141429
EGL_BLUE_SIZE, 8,
14151430
EGL_ALPHA_SIZE, 8,
14161431
EGL_DEPTH_SIZE, 0,
1417-
EGL_STENCIL_SIZE, GLES20Canvas.getStencilSize(),
1432+
// TODO: Find a better way to choose the stencil size
1433+
EGL_STENCIL_SIZE, mShowOverdraw ? GLES20Canvas.getStencilSize() : 0,
14181434
EGL_SURFACE_TYPE, EGL_WINDOW_BIT |
14191435
(dirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
14201436
EGL_NONE

libs/hwui/Caches.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ void Caches::initProperties() {
131131
} else {
132132
debugLayersUpdates = false;
133133
}
134+
135+
if (property_get(PROPERTY_DEBUG_OVERDRAW, property, NULL) > 0) {
136+
INIT_LOGD(" Overdraw debug enabled: %s", property);
137+
debugOverdraw = !strcmp(property, "true");
138+
} else {
139+
debugOverdraw = false;
140+
}
134141
}
135142

136143
void Caches::terminate() {
@@ -429,7 +436,9 @@ void Caches::resetScissor() {
429436

430437
void Caches::startTiling(GLuint x, GLuint y, GLuint width, GLuint height, bool opaque) {
431438
if (extensions.hasTiledRendering()) {
432-
glStartTilingQCOM(x, y, width, height, opaque ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM);
439+
glStartTilingQCOM(x, y, width, height,
440+
(opaque ? GL_NONE : GL_COLOR_BUFFER_BIT0_QCOM) |
441+
(debugOverdraw ? GL_STENCIL_BUFFER_BIT0_QCOM : 0));
433442
}
434443
}
435444

libs/hwui/Caches.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,7 @@ class ANDROID_API Caches: public Singleton<Caches> {
242242
// Misc
243243
GLint maxTextureSize;
244244
bool debugLayersUpdates;
245+
bool debugOverdraw;
245246

246247
TextureCache textureCache;
247248
LayerCache layerCache;

libs/hwui/OpenGLRenderer.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto
193193
mTilingSnapshot = mSnapshot;
194194
startTiling(mTilingSnapshot, true);
195195

196+
debugOverdraw(true, true);
197+
196198
if (!opaque) {
197199
mCaches.enableScissor();
198200
mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
@@ -230,6 +232,7 @@ void OpenGLRenderer::endTiling() {
230232
}
231233

232234
void OpenGLRenderer::finish() {
235+
renderOverdraw();
233236
endTiling();
234237

235238
if (!suppressErrorChecks()) {
@@ -264,6 +267,40 @@ void OpenGLRenderer::finish() {
264267
}
265268
}
266269

270+
void OpenGLRenderer::debugOverdraw(bool enable, bool clear) {
271+
if (mCaches.debugOverdraw && getTargetFbo() == 0) {
272+
if (clear) {
273+
mCaches.disableScissor();
274+
mCaches.stencil.clear();
275+
}
276+
if (enable) {
277+
mCaches.stencil.enableDebugWrite();
278+
} else {
279+
mCaches.stencil.disable();
280+
}
281+
}
282+
}
283+
284+
void OpenGLRenderer::renderOverdraw() {
285+
if (mCaches.debugOverdraw && getTargetFbo() == 0) {
286+
const Rect* clip = mTilingSnapshot->clipRect;
287+
288+
mCaches.enableScissor();
289+
mCaches.setScissor(clip->left, mTilingSnapshot->height - clip->bottom,
290+
clip->right - clip->left, clip->bottom - clip->top);
291+
292+
mCaches.stencil.enableDebugTest(2);
293+
drawColor(0x2f0000ff, SkXfermode::kSrcOver_Mode);
294+
mCaches.stencil.enableDebugTest(3);
295+
drawColor(0x2f00ff00, SkXfermode::kSrcOver_Mode);
296+
mCaches.stencil.enableDebugTest(4);
297+
drawColor(0x3fff0000, SkXfermode::kSrcOver_Mode);
298+
mCaches.stencil.enableDebugTest(4, true);
299+
drawColor(0x7fff0000, SkXfermode::kSrcOver_Mode);
300+
mCaches.stencil.disable();
301+
}
302+
}
303+
267304
void OpenGLRenderer::interrupt() {
268305
if (mCaches.currentProgram) {
269306
if (mCaches.currentProgram->isInUse()) {
@@ -275,12 +312,14 @@ void OpenGLRenderer::interrupt() {
275312
mCaches.unbindIndicesBuffer();
276313
mCaches.resetVertexPointers();
277314
mCaches.disbaleTexCoordsVertexArray();
315+
debugOverdraw(false, false);
278316
}
279317

280318
void OpenGLRenderer::resume() {
281319
sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
282320
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
283321
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
322+
debugOverdraw(true, false);
284323

285324
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
286325

@@ -301,6 +340,7 @@ void OpenGLRenderer::resumeAfterLayer() {
301340
sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
302341
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
303342
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
343+
debugOverdraw(true, false);
304344

305345
mCaches.resetScissor();
306346
dirtyClip();
@@ -406,7 +446,10 @@ bool OpenGLRenderer::updateLayer(Layer* layer, bool inFrame) {
406446
OpenGLRenderer* renderer = layer->renderer;
407447
Rect& dirty = layer->dirtyRect;
408448

409-
if (inFrame) endTiling();
449+
if (inFrame) {
450+
endTiling();
451+
debugOverdraw(false, false);
452+
}
410453

411454
renderer->setViewport(layer->layer.getWidth(), layer->layer.getHeight());
412455
renderer->prepareDirty(dirty.left, dirty.top, dirty.right, dirty.bottom, !layer->isBlend());
@@ -731,6 +774,7 @@ bool OpenGLRenderer::createFboLayer(Layer* layer, Rect& bounds, Rect& clip, GLui
731774
mSnapshot->orthoMatrix.load(mOrthoMatrix);
732775

733776
endTiling();
777+
debugOverdraw(false, false);
734778
// Bind texture to FBO
735779
glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo());
736780
layer->bindTexture();
@@ -779,6 +823,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
779823
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
780824
// Unbind current FBO and restore previous one
781825
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
826+
debugOverdraw(true, false);
782827

783828
startTiling(previous);
784829
}

libs/hwui/OpenGLRenderer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@ class OpenGLRenderer {
739739
*/
740740
void drawRegionRects(const Region& region);
741741

742+
void debugOverdraw(bool enable, bool clear);
743+
void renderOverdraw();
744+
742745
/**
743746
* Should be invoked every time the glScissor is modified.
744747
*/

libs/hwui/Properties.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
// Defines the size in bits of the stencil buffer
3838
// Note: Only 1 bit is required for clipping but more bits are required
3939
// to properly implement the winding fill rule when rasterizing paths
40-
#define STENCIL_BUFFER_SIZE 0
40+
#define STENCIL_BUFFER_SIZE 8
4141

4242
/**
4343
* Debug level for app developers. The value is a numeric value defined
@@ -56,11 +56,17 @@ enum DebugLevel {
5656
};
5757

5858
/**
59-
* Used to enable/disbale layers update debugging. The accepted values are
59+
* Used to enable/disable layers update debugging. The accepted values are
6060
* "true" and "false". The default value is "false".
6161
*/
6262
#define PROPERTY_DEBUG_LAYERS_UPDATES "debug.hwui.show_layers_updates"
6363

64+
/**
65+
* Used to enable/disable overdraw debugging. The accepted values are
66+
* "true" and "false". The default value is "false".
67+
*/
68+
#define PROPERTY_DEBUG_OVERDRAW "debug.hwui.show_overdraw"
69+
6470
// These properties are defined in mega-bytes
6571
#define PROPERTY_TEXTURE_CACHE_SIZE "ro.hwui.texture_cache_size"
6672
#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"

libs/hwui/Stencil.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ void Stencil::clear() {
3737
void Stencil::enableTest() {
3838
if (mState != kTest) {
3939
enable();
40-
glStencilFunc(GL_EQUAL, 0x0, 0x1);
40+
glStencilFunc(GL_EQUAL, 0x1, 0x1);
4141
// We only want to test, let's keep everything
4242
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
4343
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@@ -56,8 +56,27 @@ void Stencil::enableWrite() {
5656
}
5757
}
5858

59+
void Stencil::enableDebugTest(GLint value, bool greater) {
60+
enable();
61+
glStencilFunc(greater ? GL_LESS : GL_EQUAL, value, 0xffffffff);
62+
// We only want to test, let's keep everything
63+
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
64+
mState = kTest;
65+
}
66+
67+
void Stencil::enableDebugWrite() {
68+
if (mState != kWrite) {
69+
enable();
70+
glStencilFunc(GL_ALWAYS, 0x1, 0xffffffff);
71+
// The test always passes so the first two values are meaningless
72+
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
73+
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
74+
mState = kWrite;
75+
}
76+
}
77+
5978
void Stencil::enable() {
60-
if (!mState == kDisabled) {
79+
if (mState == kDisabled) {
6180
glEnable(GL_STENCIL_TEST);
6281
}
6382
}

libs/hwui/Stencil.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ class ANDROID_API Stencil {
5858
*/
5959
void enableWrite();
6060

61+
/**
62+
* The test passes only when equal to the specified value.
63+
*/
64+
void enableDebugTest(GLint value, bool greater = false);
65+
66+
/**
67+
* Used for debugging. The stencil test always passes and increments.
68+
*/
69+
void enableDebugWrite();
70+
6171
/**
6272
* Disables stencil test and write.
6373
*/

0 commit comments

Comments
 (0)