diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/AbstractDrawCommand.java b/ReactAndroid/src/main/java/com/facebook/react/flat/AbstractDrawCommand.java index 89f22b0eb..f6576d719 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/AbstractDrawCommand.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/AbstractDrawCommand.java @@ -11,6 +11,8 @@ package com.facebook.react.flat; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Typeface; /** * Base class for all DrawCommands. Becomes immutable once it has its bounds set. Until then, a @@ -33,6 +35,11 @@ import android.graphics.Color; private float mClipRight; private float mClipBottom; + // Used to draw highlights in debug draw. + private static Paint sDebugHighlightRed; + private static Paint sDebugHighlightYellow; + private static Paint sDebugHighlightOverlayText; + public final boolean clipBoundsMatch( float clipLeft, float clipTop, @@ -104,8 +111,48 @@ import android.graphics.Color; return getClass().getSimpleName().substring(4); } + private void initDebugHighlightResources(FlatViewGroup parent) { + if (sDebugHighlightRed == null) { + sDebugHighlightRed = new Paint(); + sDebugHighlightRed.setARGB(75, 255, 0, 0); + } + if (sDebugHighlightYellow == null) { + sDebugHighlightYellow = new Paint(); + sDebugHighlightYellow.setARGB(100, 255, 204, 0); + } + if (sDebugHighlightOverlayText == null) { + sDebugHighlightOverlayText = new Paint(); + sDebugHighlightOverlayText.setAntiAlias(true); + sDebugHighlightOverlayText.setARGB(200, 50, 50, 50); + sDebugHighlightOverlayText.setTextAlign(Paint.Align.RIGHT); + sDebugHighlightOverlayText.setTypeface(Typeface.MONOSPACE); + sDebugHighlightOverlayText.setTextSize(parent.dipsToPixels(9)); + } + } + + private void debugDrawHighlightRect(Canvas canvas, Paint paint, String text) { + canvas.drawRect(getLeft(), getTop(), getRight(), getBottom(), paint); + canvas.drawText(text, getRight() - 5, getBottom() - 5, sDebugHighlightOverlayText); + } + + protected void debugDrawWarningHighlight(Canvas canvas, String text) { + debugDrawHighlightRect(canvas, sDebugHighlightRed, text); + } + + protected void debugDrawCautionHighlight(Canvas canvas, String text) { + debugDrawHighlightRect(canvas, sDebugHighlightYellow, text); + } + @Override - public void debugDraw(FlatViewGroup parent, Canvas canvas) { + public final void debugDraw(FlatViewGroup parent, Canvas canvas) { + onDebugDraw(parent, canvas); + if (FlatViewGroup.DEBUG_HIGHLIGHT_PERFORMANCE_ISSUES) { + initDebugHighlightResources(parent); + onDebugDrawHighlight(canvas); + } + } + + protected void onDebugDraw(FlatViewGroup parent, Canvas canvas) { parent.debugDrawNamedRect( canvas, getDebugBorderColor(), @@ -116,6 +163,9 @@ import android.graphics.Color; mBottom); } + protected void onDebugDrawHighlight(Canvas canvas) { + } + protected void onPreDraw(FlatViewGroup parent, Canvas canvas) { } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java index 81fe946a4..f9d37a1b2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithDrawee.java @@ -301,4 +301,11 @@ import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult; // not doing this just to save including eyt another BUCK dependency return LOCAL_FILE_SCHEME.equals(type) || LOCAL_CONTENT_SCHEME.equals(type); } + + @Override + protected void onDebugDrawHighlight(Canvas canvas) { + if (mCallback != null) { + debugDrawCautionHighlight(canvas, "Invalidate Drawee"); + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithPipeline.java b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithPipeline.java index 50fa00771..bc3e94d44 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithPipeline.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawImageWithPipeline.java @@ -308,4 +308,11 @@ import com.facebook.react.views.imagehelper.MultiSourceHelper.MultiSourceResult; return mPathForRoundedBitmap; } + + @Override + protected void onDebugDrawHighlight(Canvas canvas) { + if (mCallback != null) { + debugDrawCautionHighlight(canvas, "Invalidate Pipeline"); + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawView.java b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawView.java index 2180d3596..b378ab22d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/DrawView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/DrawView.java @@ -201,7 +201,35 @@ import android.graphics.RectF; } @Override - public void debugDraw(FlatViewGroup parent, Canvas canvas) { + protected void onDebugDraw(FlatViewGroup parent, Canvas canvas) { parent.debugDrawNextChild(canvas); } + + @Override + protected void onDebugDrawHighlight(Canvas canvas) { + if (mPath != null) { + debugDrawWarningHighlight(canvas, "borderRadius: " + mClipRadius); + } else if (!boundsMatch(mLogicalLeft, mLogicalTop, mLogicalRight, mLogicalBottom)) { + StringBuilder warn = new StringBuilder("Overflow: { "); + String[] names = { "left: ", "top: ", "right: ", "bottom: "}; + int i = 0; + float[] offsets = new float[4]; + offsets[i++] = getLeft() - mLogicalLeft; + offsets[i++] = getTop() - mLogicalTop; + offsets[i++] = mLogicalRight - getRight(); + offsets[i++] = mLogicalBottom - getBottom(); + + for (i = 0; i < 4; i++) { + if (offsets[i] != 0f) { + warn.append(names[i]); + warn.append(offsets[i]); + warn.append(", "); + } + } + + warn.append("}"); + + debugDrawCautionHighlight(canvas, warn.toString()); + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java index 53c01d20e..35e84881c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/flat/FlatViewGroup.java @@ -21,6 +21,7 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.util.SparseArray; import android.util.SparseIntArray; @@ -137,9 +138,13 @@ import com.facebook.react.views.view.ReactClippingViewGroup; } } - // Resources for debug drawing. - private static final boolean DEBUG_DRAW = false; + // Draws the name of the draw commands at the bottom right corner of it's bounds. private static final boolean DEBUG_DRAW_TEXT = false; + // Draws colored rectangles over known performance issues. + /* package */ static final boolean DEBUG_HIGHLIGHT_PERFORMANCE_ISSUES = false; + // Force layout bounds drawing. This can also be enabled by turning on layout bounds in Android. + private static final boolean DEBUG_DRAW = DEBUG_DRAW_TEXT || DEBUG_HIGHLIGHT_PERFORMANCE_ISSUES; + // Resources for debug drawing. private boolean mAndroidDebugDraw; private static Paint sDebugTextPaint; private static Paint sDebugTextBackgroundPaint; @@ -347,7 +352,7 @@ import com.facebook.react.views.view.ReactClippingViewGroup; } // Used in debug drawing. - private int dipsToPixels(int dips) { + /* package */ int dipsToPixels(int dips) { float scale = getResources().getDisplayMetrics().density; return (int) (dips * scale + 0.5f); } @@ -408,6 +413,8 @@ import com.facebook.react.views.view.ReactClippingViewGroup; sDebugTextPaint = new Paint(); sDebugTextPaint.setTextAlign(Paint.Align.RIGHT); sDebugTextPaint.setTextSize(dipsToPixels(9)); + sDebugTextPaint.setTypeface(Typeface.MONOSPACE); + sDebugTextPaint.setAntiAlias(true); sDebugTextPaint.setColor(Color.RED); } if (sDebugTextBackgroundPaint == null) {