fix: add TracingEditorRenderer to analyze editor's drawing performance

This commit is contained in:
Akash Yadav
2023-10-26 19:45:31 +05:30
parent 72621d6d98
commit dd8dca9a7c
5 changed files with 291 additions and 5 deletions
+3 -1
View File
@@ -33,7 +33,9 @@ dependencies {
implementation(libs.androidx.annotation)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.tracing)
implementation(libs.androidx.tracing.ktx)
implementation(libs.common.utilcode)
implementation(libs.google.material)
@@ -0,0 +1,285 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AndroidIDE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.editor.ui
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.RenderNode
import android.os.Build
import androidx.annotation.RequiresApi
import com.itsaky.androidide.editor.BuildConfig
import io.github.rosemoe.sora.lang.styling.CodeBlock
import io.github.rosemoe.sora.lang.styling.Spans
import io.github.rosemoe.sora.text.ContentLine
import io.github.rosemoe.sora.util.LongArrayList
import io.github.rosemoe.sora.util.MutableInt
import io.github.rosemoe.sora.widget.CodeEditor
import io.github.rosemoe.sora.widget.EditorRenderer
/**
* An implementation of [EditorRenderer] which traces the whole drawing process for [IDEEditor].
*
* @author Akash Yadav
*/
class TracingEditorRenderer(
private val enabled: Boolean = BuildConfig.DEBUG,
editor: CodeEditor
) : EditorRenderer(editor) {
override fun draw(canvas: Canvas) = trace("draw") {
super.draw(canvas)
}
@RequiresApi(Build.VERSION_CODES.Q)
override fun updateLineDisplayList(renderNode: RenderNode?, line: Int, spans: Spans.Reader?) =
trace("updateLineDisplayList") {
super.updateLineDisplayList(renderNode, line, spans)
}
override fun drawSingleTextLine(canvas: Canvas?, line: Int, offsetX: Float, offsetY: Float,
spans: Spans.Reader?, visibleOnly: Boolean) = trace("drawSingleTextLine") {
super.drawSingleTextLine(canvas, line, offsetX, offsetY, spans, visibleOnly)
}
override fun drawView(canvas: Canvas?) = trace("drawView") {
super.drawView(canvas)
}
override fun drawUserGutterBackground(canvas: Canvas?, right: Int) =
trace("drawUserGutterBackground") {
super.drawUserGutterBackground(canvas, right)
}
override fun drawStuckLineNumbers(canvas: Canvas?, candidates: MutableList<CodeBlock>?,
offset: Float, lineNumberWidth: Float, lineNumberColor: Int) = trace("drawStuckLineNumbers") {
super.drawStuckLineNumbers(canvas, candidates, offset, lineNumberWidth, lineNumberColor)
}
override fun drawStuckLines(canvas: Canvas?, candidates: MutableList<CodeBlock>?, offset: Float) =
trace("drawStuckLines") {
super.drawStuckLines(canvas, candidates, offset)
}
override fun drawHardwrapMarker(canvas: Canvas?, offset: Float) = trace("drawHardwrapMarker") {
super.drawHardwrapMarker(canvas, offset)
}
override fun drawSideIcons(canvas: Canvas?, offset: Float) = trace("drawSideIcons") {
super.drawSideIcons(canvas, offset)
}
override fun drawFormatTip(canvas: Canvas?) = trace("drawFormatTip") {
super.drawFormatTip(canvas)
}
override fun drawColor(canvas: Canvas?, color: Int, rect: RectF?) = trace("drawColor") {
super.drawColor(canvas, color, rect)
}
override fun drawColor(canvas: Canvas?, color: Int, rect: Rect?) = trace("drawColor") {
super.drawColor(canvas, color, rect)
}
override fun drawColorRound(canvas: Canvas?, color: Int, rect: RectF?) = trace("drawColorRound") {
super.drawColorRound(canvas, color, rect)
}
override fun drawRowBackground(canvas: Canvas?, color: Int, row: Int) =
trace("drawRowBackground") {
super.drawRowBackground(canvas, color, row)
}
override fun drawRowBackground(canvas: Canvas?, color: Int, row: Int, right: Int) =
trace("drawRowBackground") {
super.drawRowBackground(canvas, color, row, right)
}
override fun drawLineNumber(canvas: Canvas?, line: Int, row: Int, offsetX: Float, width: Float,
color: Int) = trace("drawLineNumber") {
super.drawLineNumber(canvas, line, row, offsetX, width, color)
}
override fun drawLineNumberBackground(canvas: Canvas?, offsetX: Float, width: Float, color: Int) =
trace("drawLineNumberBackground") {
super.drawLineNumberBackground(canvas, offsetX, width, color)
}
override fun drawDivider(canvas: Canvas?, offsetX: Float, color: Int) = trace("drawDivider") {
super.drawDivider(canvas, offsetX, color)
}
override fun drawRows(canvas: Canvas?, offset: Float, postDrawLineNumbers: LongArrayList?,
postDrawCursor: MutableList<DrawCursorTask>?, postDrawCurrentLines: LongArrayList?,
requiredFirstLn: MutableInt?) = trace("drawRows") {
super.drawRows(canvas, offset, postDrawLineNumbers, postDrawCursor, postDrawCurrentLines,
requiredFirstLn)
}
override fun drawDiagnosticIndicators(canvas: Canvas?, offset: Float) =
trace("drawDiagnosticIndicators") {
super.drawDiagnosticIndicators(canvas, offset)
}
override fun drawWhitespaces(canvas: Canvas?, offset: Float, line: Int, row: Int, rowStart: Int,
rowEnd: Int, min: Int, max: Int) = trace("drawWhitespaces") {
super.drawWhitespaces(canvas, offset, line, row, rowStart, rowEnd, min, max)
}
override fun drawMiniGraph(canvas: Canvas?, offset: Float, row: Int, graph: String?) =
trace("drawMiniGraph") {
super.drawMiniGraph(canvas, offset, row, graph)
}
override fun getRowTopForBackground(row: Int) = trace("getRowTopForBackground") {
return@trace super.getRowTopForBackground(row)
}
override fun getRowBottomForBackground(row: Int) = trace("getRowBottomForBackground") {
return@trace super.getRowBottomForBackground(row)
}
override fun drawRowRegionBackground(canvas: Canvas?, row: Int, line: Int, highlightStart: Int,
highlightEnd: Int, rowStart: Int, rowEnd: Int, color: Int) = trace("drawRowRegionBackground") {
super.drawRowRegionBackground(canvas, row, line, highlightStart, highlightEnd, rowStart, rowEnd,
color)
}
override fun drawRowBackgroundRect(canvas: Canvas?, rect: RectF?) =
trace("drawRowBackgroundRect") {
super.drawRowBackgroundRect(canvas, rect)
}
override fun drawRegionText(canvas: Canvas?, offsetX: Float, baseline: Float, line: Int,
startIndex: Int, endIndex: Int, contextStart: Int, contextEnd: Int, isRtl: Boolean,
columnCount: Int, color: Int) = trace("drawRegionText") {
super.drawRegionText(canvas, offsetX, baseline, line, startIndex, endIndex, contextStart,
contextEnd, isRtl, columnCount, color)
}
override fun drawRegionTextDirectional(canvas: Canvas?, offsetX: Float, baseline: Float,
line: Int, startIndex: Int, endIndex: Int, contextStart: Int, contextEnd: Int, columnCount: Int,
color: Int) = trace("drawRegionTextDirectional") {
super.drawRegionTextDirectional(canvas, offsetX, baseline, line, startIndex, endIndex,
contextStart, contextEnd, columnCount, color)
}
override fun drawFunctionCharacter(canvas: Canvas?, offsetX: Float, offsetY: Float, width: Float,
ch: Char) = trace("drawFunctionCharacter") {
super.drawFunctionCharacter(canvas, offsetX, offsetY, width, ch)
}
override fun drawText(canvas: Canvas?, line: ContentLine?, index: Int, count: Int,
contextStart: Int, contextCount: Int, isRtl: Boolean, offX: Float, offY: Float,
lineNumber: Int) = trace("drawText") {
super.drawText(canvas, line, index, count, contextStart, contextCount, isRtl, offX, offY,
lineNumber)
}
override fun drawTextRunDirect(canvas: Canvas?, src: CharArray?, index: Int, count: Int,
contextStart: Int, contextCount: Int, offX: Float, offY: Float, isRtl: Boolean) =
trace("drawTextRunDirect") {
super.drawTextRunDirect(canvas, src, index, count, contextStart, contextCount, offX, offY,
isRtl)
}
override fun drawEdgeEffect(canvas: Canvas?) = trace("drawEdgeEffect") {
super.drawEdgeEffect(canvas)
}
override fun drawBlockLines(canvas: Canvas?, offsetX: Float) = trace("drawBlockLines") {
super.drawBlockLines(canvas, offsetX)
}
override fun drawSideBlockLine(canvas: Canvas?) = trace("drawSideBlockLine") {
super.drawSideBlockLine(canvas)
}
override fun drawScrollBars(canvas: Canvas?) = trace("drawScrollBars") {
super.drawScrollBars(canvas)
}
override fun drawScrollBarTrackVertical(canvas: Canvas?) = trace("drawScrollBarTrackVertical") {
super.drawScrollBarTrackVertical(canvas)
}
override fun drawScrollBarVertical(canvas: Canvas?) = trace("drawScrollBarVertical") {
super.drawScrollBarVertical(canvas)
}
override fun drawLineInfoPanel(canvas: Canvas?, topY: Float, length: Float) =
trace("drawLineInfoPanel") {
super.drawLineInfoPanel(canvas, topY, length)
}
override fun drawScrollBarTrackHorizontal(canvas: Canvas?) =
trace("drawScrollBarTrackHorizontal") {
super.drawScrollBarTrackHorizontal(canvas)
}
override fun patchSnippetRegions(canvas: Canvas?, textOffset: Float) =
trace("patchSnippetRegions") {
super.patchSnippetRegions(canvas, textOffset)
}
override fun patchHighlightedDelimiters(canvas: Canvas?, textOffset: Float) =
trace("patchHighlightedDelimiters") {
super.patchHighlightedDelimiters(canvas, textOffset)
}
override fun patchTextRegionWithColor(canvas: Canvas?, textOffset: Float, start: Int, end: Int,
color: Int, backgroundColor: Int, underlineColor: Int) = trace("patchTextRegionWithColor") {
super.patchTextRegionWithColor(canvas, textOffset, start, end, color, backgroundColor,
underlineColor)
}
override fun patchTextRegions(canvas: Canvas?, textOffset: Float,
positions: MutableList<TextDisplayPosition>?, patch: PatchDraw) = trace("patchTextRegions") {
super.patchTextRegions(canvas, textOffset, positions, patch)
}
override fun drawSelectionOnAnimation(canvas: Canvas?) = trace("drawSelectionOnAnimation") {
super.drawSelectionOnAnimation(canvas)
}
override fun drawScrollBarHorizontal(canvas: Canvas?) = trace("drawScrollBarHorizontal") {
super.drawScrollBarHorizontal(canvas)
}
override fun buildMeasureCacheForLines(startLine: Int, endLine: Int, timestamp: Long,
useCachedContent: Boolean) = trace("buildMeasureCacheForLines") {
super.buildMeasureCacheForLines(startLine, endLine, timestamp, useCachedContent)
}
override fun buildMeasureCacheForLines(startLine: Int, endLine: Int) =
trace("buildMeasureCacheForLines") {
super.buildMeasureCacheForLines(startLine, endLine)
}
override fun measureText(text: ContentLine?, line: Int, index: Int, count: Int) =
trace("measureText") {
return@trace super.measureText(text, line, index, count)
}
private inline fun <T : Any?> trace(section: String, crossinline action: () -> T): T =
if (enabled) {
androidx.tracing.trace(section, action)
} else {
action()
}
}