implements PLN-0083
This commit is contained in:
parent
0be02622c4
commit
e17344af63
@ -1,5 +1,5 @@
|
||||
{"type":"meta","next_id":{"DSC":39,"AGD":42,"DEC":38,"PLN":87,"LSN":53,"CLSN":1}}
|
||||
{"type":"discussion","id":"DSC-0038","status":"open","ticket":"studio-packer-rgba8888-asset-pipeline","title":"Studio and Packer RGBA8888 Asset Pipeline Alignment","created_at":"2026-05-23","updated_at":"2026-05-23","tags":["studio","packer","assets","glyph-bank","palette","rgba8888","runtime-alignment"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0081","file":"PLN-0081-rgba8888-packer-and-studio-spec-propagation.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0082","file":"PLN-0082-rgba8888-palette-model-and-argb-conversion.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0083","file":"PLN-0083-rgba8888-glyph-payload-emission-and-sizes.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0084","file":"PLN-0084-rgba8888-packer-projections-and-workspace-apis.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0085","file":"PLN-0085-rgba8888-tests-fixtures-and-conformance.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0086","file":"PLN-0086-rgba8888-final-integration-and-residue-removal.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]}],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0038","status":"open","ticket":"studio-packer-rgba8888-asset-pipeline","title":"Studio and Packer RGBA8888 Asset Pipeline Alignment","created_at":"2026-05-23","updated_at":"2026-05-23","tags":["studio","packer","assets","glyph-bank","palette","rgba8888","runtime-alignment"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-studio-packer-rgba8888-asset-pipeline.md","status":"accepted","created_at":"2026-05-23","updated_at":"2026-05-23","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0081","file":"PLN-0081-rgba8888-packer-and-studio-spec-propagation.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0082","file":"PLN-0082-rgba8888-palette-model-and-argb-conversion.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0083","file":"PLN-0083-rgba8888-glyph-payload-emission-and-sizes.md","status":"done","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0084","file":"PLN-0084-rgba8888-packer-projections-and-workspace-apis.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0085","file":"PLN-0085-rgba8888-tests-fixtures-and-conformance.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]},{"id":"PLN-0086","file":"PLN-0086-rgba8888-final-integration-and-residue-removal.md","status":"review","created_at":"2026-05-23","updated_at":"2026-05-23","ref_decisions":["DEC-0037"]}],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0037","status":"done","ticket":"pbs-autocomplete-parameter-names","title":"PBS autocomplete parameter names for stdlib and method calls","created_at":"2026-05-08","updated_at":"2026-05-14","tags":["compiler-pbs","studio","lsp","autocomplete","signature-help","stdlib"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0052","file":"discussion/lessons/DSC-0037-pbs-autocomplete-parameter-names/LSN-0052-canonical-callable-parameter-names-through-pbs-editor-assistance.md","status":"done","created_at":"2026-05-14","updated_at":"2026-05-14"}]}
|
||||
{"type":"discussion","id":"DSC-0036","status":"open","ticket":"pbs-symbol-documentation-and-hover-markdown","title":"Modelo de documentacao de simbolos em PBS e consumo markdown no hover","created_at":"2026-05-08","updated_at":"2026-05-08","tags":["compiler","compiler-pbs","studio","lsp","vscode","editor","hover","documentation","markdown"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-pbs-symbol-documentation-and-hover-markdown.md","status":"open","created_at":"2026-05-08","updated_at":"2026-05-08"}],"decisions":[],"plans":[],"lessons":[]}
|
||||
{"type":"discussion","id":"DSC-0035","status":"done","ticket":"pbs-lsp-editor-assistance-wave-1","title":"Wave 1 de assistencia editorial via LSP para PBS no VS Code","created_at":"2026-05-08","updated_at":"2026-05-08","tags":["studio","lsp","vscode","compiler","compiler-pbs","editor","completion","hover","signature-help"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0051","file":"discussion/lessons/DSC-0035-pbs-lsp-editor-assistance-wave-1/LSN-0051-compiler-backed-editor-assistance-for-pbs.md","status":"done","created_at":"2026-05-08","updated_at":"2026-05-08"}]}
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
id: PLN-0083
|
||||
ticket: studio-packer-rgba8888-asset-pipeline
|
||||
title: RGBA8888 Glyph Payload Emission and Size Accounting
|
||||
status: review
|
||||
status: done
|
||||
created: 2026-05-23
|
||||
completed:
|
||||
completed: 2026-05-23
|
||||
ref_decisions:
|
||||
- DEC-0037
|
||||
tags:
|
||||
@ -126,12 +126,12 @@ index into the referenced glyph palette.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Glyph payloads keep `GLYPH/indexed_v1`.
|
||||
- [ ] Glyph palette blocks are 4096 bytes.
|
||||
- [ ] Palette entries are emitted as RGBA bytes in runtime channel order.
|
||||
- [ ] No synthetic magenta/color-key value is emitted.
|
||||
- [ ] Size and decoded-size metadata match the new payload length.
|
||||
- [ ] Scene `palette_id` payload shape is unchanged.
|
||||
- [x] Glyph payloads keep `GLYPH/indexed_v1`.
|
||||
- [x] Glyph palette blocks are 4096 bytes.
|
||||
- [x] Palette entries are emitted as RGBA bytes in runtime channel order.
|
||||
- [x] No synthetic magenta/color-key value is emitted.
|
||||
- [x] Size and decoded-size metadata match the new payload length.
|
||||
- [x] Scene `palette_id` payload shape is unchanged.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
||||
@ -38,7 +38,11 @@ import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class FileSystemPackerWorkspaceService implements PackerWorkspaceService {
|
||||
private static final int GLYPH_BANK_COLOR_KEY_RGB565 = 0xF81F;
|
||||
private static final int GLYPH_BANK_PALETTE_COUNT = 64;
|
||||
private static final int GLYPH_BANK_COLORS_PER_PALETTE = 16;
|
||||
private static final int GLYPH_BANK_RGBA8888_BYTES_PER_COLOR = 4;
|
||||
private static final int GLYPH_BANK_PALETTE_BYTES =
|
||||
GLYPH_BANK_PALETTE_COUNT * GLYPH_BANK_COLORS_PER_PALETTE * GLYPH_BANK_RGBA8888_BYTES_PER_COLOR;
|
||||
private static final String SCENE_BANK_SUPPORT_FILE = "scene-bank.studio.json";
|
||||
private static final String SCENE_PACK_REQUEST_FILE = "scene-bank.pack-request.json";
|
||||
|
||||
@ -1091,7 +1095,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
final byte[] sheetPixels = new byte[width * height];
|
||||
final Map<String, PackerRuntimeWalkFile> selectedByPath = new LinkedHashMap<>();
|
||||
runtimeAsset.walkProjection().buildCandidateFiles().forEach(file -> selectedByPath.put(file.relativePath(), file));
|
||||
final Map<Integer, Integer> declaredPaletteIndexByRgb = declaredPaletteIndexByRgb(declaration);
|
||||
final Map<Integer, Integer> declaredPaletteIndexByRgba = declaredPaletteIndexByRgba(declaration);
|
||||
|
||||
declaration.artifacts().stream()
|
||||
.sorted(Comparator.comparingInt(PackerAssetArtifactSelection::index))
|
||||
@ -1108,7 +1112,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
tile,
|
||||
walkFile.metadata().get("palette"),
|
||||
artifact.file(),
|
||||
declaredPaletteIndexByRgb);
|
||||
declaredPaletteIndexByRgba);
|
||||
final int tileX = (artifact.index() % tilesPerRow) * tileSize;
|
||||
final int tileY = (artifact.index() / tilesPerRow) * tileSize;
|
||||
for (int localY = 0; localY < tile.height(); localY += 1) {
|
||||
@ -1130,7 +1134,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
runtimeMetadata.put("tile_size", tileSize);
|
||||
runtimeMetadata.put("width", width);
|
||||
runtimeMetadata.put("height", height);
|
||||
runtimeMetadata.put("palette_count", 64);
|
||||
runtimeMetadata.put("palette_count", GLYPH_BANK_PALETTE_COUNT);
|
||||
runtimeMetadata.put("palette_authored", countAuthoredGlyphBankPalettes(declaration));
|
||||
runtimeMetadata.put("codec", Map.of());
|
||||
declaration.outputMetadata().forEach((key, value) -> {
|
||||
@ -1150,7 +1154,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
"GLYPH",
|
||||
"NONE",
|
||||
payload,
|
||||
width * height + 2048,
|
||||
width * height + GLYPH_BANK_PALETTE_BYTES,
|
||||
runtimeMetadata,
|
||||
toolingMetadata,
|
||||
declaration.preloadEnabled());
|
||||
@ -1160,7 +1164,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
PackerTileIndexedV1 tile,
|
||||
Object paletteMetadata,
|
||||
String artifactFile,
|
||||
Map<Integer, Integer> declaredPaletteIndexByRgb) {
|
||||
Map<Integer, Integer> declaredPaletteIndexByRgba) {
|
||||
final int[] rgba8888 = paletteColors(paletteMetadata);
|
||||
if (rgba8888.length == 0) {
|
||||
throw new IllegalStateException("Selected tile artifact is missing palette metadata required for palette remapping: " + artifactFile);
|
||||
@ -1172,7 +1176,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
throw new IllegalStateException("Tile palette index exceeds discovered palette size for artifact: " + artifactFile);
|
||||
}
|
||||
final int rgba = rgba8888[paletteIndex];
|
||||
final Integer materialIndex = declaredPaletteIndexByRgb.get(rgba);
|
||||
final Integer materialIndex = declaredPaletteIndexByRgba.get(rgba);
|
||||
if (materialIndex == null || materialIndex < 0 || materialIndex > 15) {
|
||||
throw new IllegalStateException("Unable to resolve canonical palette index for artifact color in " + artifactFile);
|
||||
}
|
||||
@ -1181,7 +1185,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
return remapped;
|
||||
}
|
||||
|
||||
private Map<Integer, Integer> declaredPaletteIndexByRgb(PackerAssetDeclaration declaration) {
|
||||
private Map<Integer, Integer> declaredPaletteIndexByRgba(PackerAssetDeclaration declaration) {
|
||||
final JsonNode palettesNode = declaration.outputPipelineMetadata().get("palettes");
|
||||
if (!(palettesNode instanceof ArrayNode palettesArray) || palettesArray.isEmpty()) {
|
||||
throw new IllegalStateException("Glyph packing requires at least one declared pipeline palette.");
|
||||
@ -1272,7 +1276,7 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
}
|
||||
|
||||
private byte[] emitGlyphBankPalettes(PackerAssetDeclaration declaration) {
|
||||
final byte[] bytes = new byte[64 * 16 * 2];
|
||||
final byte[] bytes = new byte[GLYPH_BANK_PALETTE_BYTES];
|
||||
final JsonNode palettesNode = declaration.outputPipelineMetadata().get("palettes");
|
||||
if (!(palettesNode instanceof com.fasterxml.jackson.databind.node.ArrayNode palettesArray)) {
|
||||
return bytes;
|
||||
@ -1284,21 +1288,21 @@ public final class FileSystemPackerWorkspaceService implements PackerWorkspaceSe
|
||||
continue;
|
||||
}
|
||||
final int paletteIndex = indexNode.intValue();
|
||||
if (paletteIndex < 0 || paletteIndex >= 64) {
|
||||
if (paletteIndex < 0 || paletteIndex >= GLYPH_BANK_PALETTE_COUNT) {
|
||||
continue;
|
||||
}
|
||||
final int paletteBaseOffset = (paletteIndex * 16) * 2;
|
||||
bytes[paletteBaseOffset] = (byte) (GLYPH_BANK_COLOR_KEY_RGB565 & 0xFF);
|
||||
bytes[paletteBaseOffset + 1] = (byte) ((GLYPH_BANK_COLOR_KEY_RGB565 >>> 8) & 0xFF);
|
||||
final JsonNode convertedNode = paletteNode.path("convertedRgb565");
|
||||
if (!convertedNode.isArray()) {
|
||||
final JsonNode rgbaNode = paletteNode.path("rgba8888");
|
||||
if (!rgbaNode.isArray()) {
|
||||
continue;
|
||||
}
|
||||
for (int colorIndex = 0; colorIndex < Math.min(15, convertedNode.size()); colorIndex += 1) {
|
||||
final int rgb565 = convertedNode.get(colorIndex).asInt(0);
|
||||
final int baseOffset = ((paletteIndex * 16) + colorIndex + 1) * 2;
|
||||
bytes[baseOffset] = (byte) (rgb565 & 0xFF);
|
||||
bytes[baseOffset + 1] = (byte) ((rgb565 >>> 8) & 0xFF);
|
||||
for (int colorIndex = 0; colorIndex < Math.min(GLYPH_BANK_COLORS_PER_PALETTE, rgbaNode.size()); colorIndex += 1) {
|
||||
final int rgba = rgbaNode.get(colorIndex).asInt(0);
|
||||
final int baseOffset = ((paletteIndex * GLYPH_BANK_COLORS_PER_PALETTE) + colorIndex)
|
||||
* GLYPH_BANK_RGBA8888_BYTES_PER_COLOR;
|
||||
bytes[baseOffset] = (byte) ((rgba >>> 24) & 0xFF);
|
||||
bytes[baseOffset + 1] = (byte) ((rgba >>> 16) & 0xFF);
|
||||
bytes[baseOffset + 2] = (byte) ((rgba >>> 8) & 0xFF);
|
||||
bytes[baseOffset + 3] = (byte) (rgba & 0xFF);
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user