feat(profiler): expose scene picture and flush timings
This commit is contained in:
parent
1326aac68d
commit
faaa741911
|
|
@ -116,6 +116,14 @@ function canUseScenePicture(
|
|||
)
|
||||
}
|
||||
|
||||
const now = typeof performance !== 'undefined' ? () => performance.now() : () => 0
|
||||
|
||||
function measure<T>(fn: () => T): { value: T; duration: number } {
|
||||
const start = now()
|
||||
const value = fn()
|
||||
return { value, duration: now() - start }
|
||||
}
|
||||
|
||||
export function render(
|
||||
r: SkiaRenderer,
|
||||
graph: SceneGraph,
|
||||
|
|
@ -126,6 +134,9 @@ export function render(
|
|||
): void {
|
||||
const p = r.profiler
|
||||
p.beginFrame()
|
||||
p.setScenePictureDrawTime(0)
|
||||
p.setScenePictureRecordTime(0)
|
||||
p.setFlushTime(0)
|
||||
|
||||
graph.clearAbsPosCache()
|
||||
|
||||
|
|
@ -167,7 +178,11 @@ export function render(
|
|||
if (canUsePicture) {
|
||||
p.setScenePictureMode('hit')
|
||||
p.beginPhase('render:drawPicture')
|
||||
if (r.scenePicture) canvas.drawPicture(r.scenePicture)
|
||||
if (r.scenePicture) {
|
||||
const picture = r.scenePicture
|
||||
const { duration } = measure(() => canvas.drawPicture(picture))
|
||||
p.setScenePictureDrawTime(duration)
|
||||
}
|
||||
p.endPhase('render:drawPicture')
|
||||
} else if (hasVolatileOverlays) {
|
||||
p.setScenePictureMode('volatile', cacheMissReason)
|
||||
|
|
@ -181,7 +196,8 @@ export function render(
|
|||
r._nodeCount = 0
|
||||
r._culledCount = 0
|
||||
p.beginPhase('render:recordPicture')
|
||||
recordScenePicture(r, canvas, graph, sceneVersion)
|
||||
const { duration } = measure(() => recordScenePicture(r, canvas, graph, sceneVersion))
|
||||
p.setScenePictureRecordTime(duration)
|
||||
p.endPhase('render:recordPicture')
|
||||
}
|
||||
p.endPhase('render:scene')
|
||||
|
|
@ -231,7 +247,8 @@ export function render(
|
|||
}
|
||||
|
||||
p.beginPhase('render:flush')
|
||||
r.surface.flush()
|
||||
const { duration: flushDuration } = measure(() => r.surface.flush())
|
||||
p.setFlushTime(flushDuration)
|
||||
p.endPhase('render:flush')
|
||||
|
||||
p.setNodeCounts(r._nodeCount, r._culledCount)
|
||||
|
|
|
|||
|
|
@ -29,6 +29,11 @@ export function createFrameCapture(
|
|||
culledNodes: stats.culledNodes,
|
||||
drawCalls: stats.drawCalls,
|
||||
scenePictureCacheHit: stats.scenePictureCacheHit,
|
||||
scenePictureMode: stats.scenePictureMode,
|
||||
scenePictureMissReason: stats.scenePictureMissReason,
|
||||
scenePictureDrawTimeMs: stats.scenePictureDrawTime,
|
||||
scenePictureRecordTimeMs: stats.scenePictureRecordTime,
|
||||
flushTimeMs: stats.flushTime,
|
||||
rootProfiles: session.stack.getRootProfiles()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,11 @@ export interface FrameCapture {
|
|||
culledNodes: number
|
||||
drawCalls: number
|
||||
scenePictureCacheHit: boolean
|
||||
scenePictureMode: 'hit' | 'record' | 'volatile' | 'none'
|
||||
scenePictureMissReason: string
|
||||
scenePictureDrawTimeMs: number
|
||||
scenePictureRecordTimeMs: number
|
||||
flushTimeMs: number
|
||||
rootProfiles: NodeProfile[]
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ export class FrameStats {
|
|||
scenePictureCacheHit = false
|
||||
scenePictureMode: 'hit' | 'record' | 'volatile' | 'none' = 'none'
|
||||
scenePictureMissReason = ''
|
||||
scenePictureDrawTime = 0
|
||||
scenePictureRecordTime = 0
|
||||
flushTime = 0
|
||||
|
||||
private frameTimeBuffer = new Float64Array(BUFFER_SIZE)
|
||||
private cpuTimeBuffer = new Float64Array(BUFFER_SIZE)
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ export class HudRenderer {
|
|||
]
|
||||
const visiblePhases = phaseNames.filter((n) => (phases.get(n) ?? 0) > 0.01)
|
||||
|
||||
const statsRows = 3
|
||||
const statsRows = 4
|
||||
const phaseRows = visiblePhases.length > 0 ? 1 + visiblePhases.length : 0
|
||||
const statsHeight = (statsRows + phaseRows) * LINE_HEIGHT
|
||||
const graphSection = hasGraph ? GRAPH_HEIGHT + PADDING + LINE_HEIGHT : 0
|
||||
|
|
@ -151,6 +151,13 @@ export class HudRenderer {
|
|||
this.hudFont
|
||||
)
|
||||
canvas.drawText(`Cache: ${cacheStatus}`, col2, y, this.textPaint, this.hudFont)
|
||||
y += LINE_HEIGHT
|
||||
|
||||
const pictureLabel = stats.scenePictureMode === 'record' ? 'record' : 'picture'
|
||||
const pictureTime =
|
||||
stats.scenePictureMode === 'record' ? stats.scenePictureRecordTime : stats.scenePictureDrawTime
|
||||
canvas.drawText(`${pictureLabel}: ${pictureTime.toFixed(1)}ms`, col1, y, this.textPaint, this.hudFont)
|
||||
canvas.drawText(`flush: ${stats.flushTime.toFixed(1)}ms`, col2, y, this.textPaint, this.hudFont)
|
||||
|
||||
if (visiblePhases.length > 0) {
|
||||
y += LINE_HEIGHT
|
||||
|
|
|
|||
|
|
@ -89,6 +89,18 @@ export class RenderProfiler {
|
|||
this.stats.scenePictureMissReason = reason
|
||||
}
|
||||
|
||||
setScenePictureDrawTime(ms: number): void {
|
||||
this.stats.scenePictureDrawTime = ms
|
||||
}
|
||||
|
||||
setScenePictureRecordTime(ms: number): void {
|
||||
this.stats.scenePictureRecordTime = ms
|
||||
}
|
||||
|
||||
setFlushTime(ms: number): void {
|
||||
this.stats.flushTime = ms
|
||||
}
|
||||
|
||||
beginCapture(): void {
|
||||
this.capturing = true
|
||||
this.captureSession = createCaptureSession(now())
|
||||
|
|
|
|||
Loading…
Reference in a new issue