[AI] Stroke redraw allocates and destroys a native Onyx pen for every stroke

Abierto
#331 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 2 días

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
48/100
Tipo de issue
Refactorización
Claridad
Bastante claro
Estado de actividad
Activo
Stack tecnológico
android, kotlin

Línea de trabajo

Start by tracing PageView.drawAreaScreenCoordinates or drawOnCanvasFromPage and measure a full-page redraw on a real device, separating native pen creation and destruction from rendering. If that cost is significant, prototype reuse for the fountain V2 and square wrappers in editor/drawing/onyx/ and compare output against fresh pens. Done means the measurements justify the change and visual checks show no stroke differences.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

enhancement

Summary

When a page is (re)drawn, every stroke drawn with a Neo pen allocates a new native Onyx pen, renders one stroke with it, and destroys it. On a page with thousands of strokes that is thousands of JNI allocate/free round-trips per redraw (page open, scroll, zoom, undo, erase repaint). This may be a significant part of redraw time and needs to be measured.

Where it happens

Notable's own wrappers (editor/drawing/onyx/):

  • NeoFountainPenV2Wrapper.drawStroke: FountainShapes.createNeoPenV2(...) → NeoPenRender(neoPen) → render(...) → destroyPen(), once per stroke.
  • NeoSquarePenWrapper.drawStroke: NeoSquarePen.create(config) → NeoPenRender → destroyPen(), once per stroke.

Onyx SDK wrappers that OnyxStrokeRenderer calls (confirmed in the onyxsdk-pen 1.5.8 sources, which Onyx now publishes as -sources.jar):

  • NeoBrushPenWrapper, NeoMarkerPenWrapper and NeoFountainPenWrapper go through NeoPenUtils.computeStrokePoints, which does new NeoPenConfig() → NeoBrushPen/NeoFountainPen/NeoMarkerPen.create(config) → … → pen.destroy() per call.
  • NeoCharcoalPenWrapper / NeoCharcoalPenV2Wrapper do NeoCharcoalPen(V2).create(config) … pen.destroy() per call.
  • NeoMarkerPenWrapper.drawStroke also creates a new Canvas(...) over the shared screen-sized pen bitmap per stroke (see #309 for the related offscreen-buffer issue).

Only the ballpoint pen is rendered without a native pen.

Why reuse might be possible

From the onyxsdk-penbrush 1.1.2 sources:

  • NeoPen has no API to change its config after creation. Width and other parameters are fixed in create(config) / createNeoPenV2(width, …).
  • Each stroke is driven through onPenDown → onPenMove → onPenUp on the native handle (NeoPenNative.onPenDown(penHandle, …)), which looks like a per-stroke state machine. So one native pen per (pen type, width, other config) could probably be reused for many strokes within one redraw pass and destroyed once at the end.

Not verified: that onPenDown fully resets the native state (no carry-over of smoothing or prediction from the previous stroke), and that NeoPenRender can be reused or recreated cheaply around a reused NeoPen.

What to investigate

  1. Measure first. Time a full-page redraw on a stroke-heavy page (e.g. PageView.drawAreaScreenCoordinates / drawOnCanvasFromPage) on a real device (Note Air 4C / Note 4C). Split the time into pen create/destroy and the actual render (method tracing or manual timers around createNeoPenV2 / create / destroy).
  2. If create/destroy is significant, prototype a per-redraw pen cache for the pens we construct ourselves (fountain V2, square): key by pen type + config (width, …), reuse across strokes, destroy all at the end of the pass.
  3. Verify visually that reused pens produce identical output to fresh ones (overlay or pixel diff of a test page), especially for the fountain V2 smoothing and the first/last segments of each stroke.
  4. For the SDK-wrapped pens (brush, marker, charcoal) reuse would mean replacing NeoPenUtils.computeStrokePoints / the charcoal wrappers with our own calls against the public NeoPen API. Worth doing only if step 1 shows a real gain.

Context

Found while reviewing the Onyx SDK 1.5.8 / penbrush 1.1.2 sources during the SDK bump (notes in docs/onyx-sdk/sdk-release-changelog.md, untracked working docs).

Lenguaje dominante
Kotlin
Estrellas
269
Forks
44
Merge medio
3 d 21 h
PR fusionados (30 d)
22

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Ethran/notable

Todos los issues de Ethran/notable

Issues similares

Más issues de Kotlin

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.