Skip to content

Commit 8e586f6

Browse files
Romain GuyAndroid (Google) Code Review
authored andcommitted
Merge "Add support for a new developer setting: overdraw debugging" into jb-mr1-dev
2 parents 88923c9 + 7c450aa commit 8e586f6

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
@@ -194,6 +194,8 @@ int OpenGLRenderer::prepareDirty(float left, float top, float right, float botto
194194
mTilingSnapshot = mSnapshot;
195195
startTiling(mTilingSnapshot, true);
196196

197+
debugOverdraw(true, true);
198+
197199
if (!opaque) {
198200
mCaches.enableScissor();
199201
mCaches.setScissor(left, mSnapshot->height - bottom, right - left, bottom - top);
@@ -231,6 +233,7 @@ void OpenGLRenderer::endTiling() {
231233
}
232234

233235
void OpenGLRenderer::finish() {
236+
renderOverdraw();
234237
endTiling();
235238

236239
if (!suppressErrorChecks()) {
@@ -265,6 +268,40 @@ void OpenGLRenderer::finish() {
265268
}
266269
}
267270

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

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

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

@@ -302,6 +341,7 @@ void OpenGLRenderer::resumeAfterLayer() {
302341
sp<Snapshot> snapshot = (mSnapshot != NULL) ? mSnapshot : mFirstSnapshot;
303342
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
304343
glBindFramebuffer(GL_FRAMEBUFFER, snapshot->fbo);
344+
debugOverdraw(true, false);
305345

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

410-
if (inFrame) endTiling();
450+
if (inFrame) {
451+
endTiling();
452+
debugOverdraw(false, false);
453+
}
411454

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

726769
endTiling();
770+
debugOverdraw(false, false);
727771
// Bind texture to FBO
728772
glBindFramebuffer(GL_FRAMEBUFFER, layer->getFbo());
729773
layer->bindTexture();
@@ -772,6 +816,7 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) {
772816
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
773817
// Unbind current FBO and restore previous one
774818
glBindFramebuffer(GL_FRAMEBUFFER, previous->fbo);
819+
debugOverdraw(true, false);
775820

776821
startTiling(previous);
777822
}

libs/hwui/OpenGLRenderer.h

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

726+
void debugOverdraw(bool enable, bool clear);
727+
void renderOverdraw();
728+
726729
/**
727730
* Should be invoked every time the glScissor is modified.
728731
*/

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)