flutter3d_hardware 0.5.1 copy "flutter3d_hardware: ^0.5.1" to clipboard
flutter3d_hardware: ^0.5.1 copied to clipboard

The graphics vocabulary flutter3d is written against: formats, handles, a command encoder and a device. Names no graphics API.

0.5.1 #

  • ShaderBundle.webgpuSection, and the format version stays at 1. A fourth backend needs a fourth section, and the container was already built to take one: the section table is a count followed by that many name-to-bytes pairs, and the only version gate is equality, so a bundle carrying WGSL is read by the Impeller and WebGL backends exactly as it was before — they count four, take theirs, and carry the rest through untouched. The doc comment says the two things the neighbouring sections do not have to. First, the payload holds reflection beside the code — uniform block names with member offsets, group-and-binding pairs for textures and samplers, attribute locations by name — because a compiled WGSL module will not answer where anything landed, and code without those answers is code a device can compile and cannot bind. Second, the payload versions itself, separately, because the shape of that reflection is an agreement between one packer and one backend and will move again while the container does not.
  • The SDK check is false for WGSL, on purpose. compiledFor compares the token impellerc was pinned to; there is no impellerc in the WebGPU path at all, because WGSL is text the browser compiles when the page loads. A bundle carrying only that section leaves sdk empty and the check answers false forever. Written down so the next reader does not take it for an oversight and invent a version to compare.
  • WindingOrder says the winding is measured in clip space. No behaviour changes; the sentence is one a reader otherwise pays for in test triangles, because a transform that mirrors flips the facing without touching the order the vertices were given in.

0.5.0 #

  • No API change. Released with the set so every floor in the workspace moves together; see doc/boundary-0.5.0.md for what the release is.

0.4.2 #

  • bindUniformBlock's contract says which of the two failures is an error. A block the compiler dropped is false; a block missing a member the caller named throws. The doc comment used to promise the opposite for members, with a reason that did not hold, and the two hardware backends had drifted apart under it. A backend with no reflection of its shaders is not asked to tell the two apart — the software rasteriser hands the block to a Dart shader that looks up what it needs by name — and the conformance suite asks a backend which kind it is rather than assuming.
  • SamplerOptions.anisotropy and GraphicsDevice.maxAnisotropy. A floor seen along its length covers a footprint a few texels tall and many wide, and a trilinear sampler picks one level for the whole of it — the level that stops the long axis aliasing blurs the short one. The field is a count of taps along that long axis, one by default so every picture is the bytes it was, checked at construction to sit on a trilinear sampler because that is flutter_gpu's rule and the taps are taken across the chain, and clamped by every backend to what the device answers, so sixteen is a safe thing to ask for. The device getter is there to decide with rather than to guard: the bridge asks it once per level. FakeBackend answers sixteen and can be told otherwise. withAnisotropy copies a sampler with the one field a caller decides at run time.
  • GraphicsDevice.loadShaders: a shader bundle arrives as bytes. The one way a shader reaches a device without being an asset, for an editor that rebuilds a bundle and wants to see it without restarting and for an application that ships a look the engine never heard of and wants it on every backend. ShaderBundle is the container — a header naming the bundle, the SDK it was compiled on and the stages it claims, then one section per backend — with encode/decode checked against each other. LoadedShaderLibrary is what comes back: a ShaderLibrary with refresh, which reparses new bytes in place and keeps the identity of every handle already handed out. ShaderBundleRefused is the one exception a device answers when it will not load a bundle, and it names the bundle: never an empty library, which would fail at the first draw naming a stage rather than the file to rebuild.
  • FakeBackend.loadShaders and FakeLoadedShaderLibrary, which keep the same identity promise so a test of a reload path proves something; FakeBackend.linkedPipelines records every pair linked, in order, so a test can tell a frame that relinked from one that did not.
  • A loaded library lives as long as the device, and loadShaders now says so: there is no release, because the handles it handed out are held by whatever resolved them, so an application whose shaders change loads one bundle and refreshes it in place. LoadedShaderLibrary also says what a pipeline linked before a refresh does until it is dropped — draws the code it had, on every backend — since one backend did not keep that.
  • A refresh that drops a stage in use is refused, naming the stage. The other half of the identity promise, and LoadedShaderLibrary.refresh now says so: a handle is the renderer's for its lifetime, so a bundle that no longer names that stage would leave a live handle over nothing — a stale pipeline on one backend, a link error on another. Every backend and the fake refuse it the same way, before anything is swapped, and the conformance suite holds them to it.
  • ShaderBundle.decode refuses a string field that is not UTF-8 as a ShaderBundleRefused, rather than letting the decoder's own FormatException out as the one exception that was not a refusal.
  • package:flutter3d_hardware/shader_bundle.dart exports the container on its own, with no Flutter behind it: the barrel reaches package:flutter through GraphicsDevice, and the tool that packs a bundle is a dart run script.
  • GraphicsDevice.readback. The pixels of a texture, or a region of it, as the passes submitted before the call left them, answered without stalling on the GPU — a copy queued in order and a future that resolves when the queue reports it done, a frame or two later. readPixels stays for the golden run and the probes, where the caller has stopped drawing and can afford to wait; this is for a caller still drawing that wants last frame's answer while this frame goes on: an exposure meter, an editor's pick. What cannot be read — tile memory, a multisampled target, a cube, a region past the edge — is refused with an ArgumentError by readbackRegionOf, once, so every backend refuses alike. A backend outside this repository has to add the member.
  • A readback is linear eight-bit RGBA or it is refused. readbackFormats names two layouts — r8g8b8a8UNormInt and b8g8r8a8UNormInt, the same four bytes in either order — and readbackRegionOf refuses any other format by name. The contract promises the same bytes on every backend, and a half-float target broke it three ways: on WebGL2 readPixels(RGBA, UNSIGNED_BYTE) of a float attachment is an INVALID_OPERATION that leaves the pack buffer at zeros and the future completing successfully with a black picture; flutter_gpu converted through toByteData; the software rasteriser clamped its floats. A float texture is read through readPixels, or drawn into an eight-bit target first, which is what the exposure meter's luminance pass is for.
  • The sRGB twins are refused too, with a message of their own. They were admitted on the grounds of being eight bits per channel, which is the wrong test: the question is whether three backends hand back the same bytes, and for an encoded texture nothing said they would — flutter_gpu reads through asImage().toByteData(rawRgba), which may hand back the linear values the encoding stands for, WebGL2 hands back what is stored, and the software rasteriser rounds its own floats. Nothing asked: every readback target the engine declares is r8g8b8a8UNormInt, so the two formats were a promise no conformance check ever made. The refusal points at the same texture's UNormInt layout rather than at drawing it into another target, because that is the different fix a different mistake needs.
  • FakeBackend.readback records what was asked — texture and region — and answers zeros unless answerReadback says otherwise, so a test can be the device that saw a dark frame or a particular id.
  • The stencil, whole. StencilState — compare, the three operations, two eight-bit masks — with StencilOperation and StencilFace mirrored from flutter_gpu value for value; PassEncoder.setStencil for one face or both and setStencilReference beside it; the same three fields on PassState, emitted after depth; and DepthTarget saying how its stencil is loaded, stored and cleared. A pass starts with the test off on both faces, whatever the pass before it set.
  • GraphicsDevice.supportsStencil, to ask before configuring a test against an attachment that has none, and TextureFormatStencil.hasStencil for the formats that carry one.
  • StencilState.narrowReference, which is where "eight bits" is decided once instead of three times. Left to themselves a software rasteriser wraps an out-of-range reference, GL clamps it and flutter_gpu forwards it, so the same value meant three things; every backend narrows through this now.
  • BlendState.keepDestination: zero from the source, one from the destination. flutter_gpu has no colour write mask and a discarded fragment writes no stencil, so this is the one way a draw marks the stencil and leaves the picture alone.
  • FakeBackend can be told it has no stencil, and FakePass records the stencil state and reference it was left with.
  • A colour attachment names a face and a level. ColorTarget.face picks a face of a cube in the order the uploads take them, ColorTarget.mipLevel a level below the base, and a pass's initial viewport covers the level. What a reflection probe is drawn into, and the first time anything in the engine renders into a face or a mip.
  • GraphicsDevice.createCubeRenderTarget allocates a cube a pass may draw into, device-private and empty, with a chain of the length asked for and trimmed to what the device will hold; supportsRenderToMip says whether a level below the base can be attached at all, which is the one capability that splits flutter_gpu by platform. FakeBackend records both and answers the capability either way.
  • PassEncoder.setBlendColor, and GraphicsDevice.supportsBlendColor beside it. Four BlendFactor values read a blend constant nothing could set, so a BlendState naming one threw on the software rasteriser and evaluated to zero on the other two — a plausible picture with a term missing from it. The setter is the missing half; the capability is there because flutter_gpu exposes no blend-constant setter at all, and a backend answering false must now refuse both the setter and a state naming one of the four rather than drawing it as zero. BlendState.usesBlendColor is where that list of four lives, so a backend cannot go on accepting a value the enum grows later.

0.4.1 #

  • GraphicsDevice.supportsTextureFormat. The question a block-compressed format needs asked and none of the backends was asking: every value of TextureFormat has a name everywhere, and BC is a desktop family, ETC2 a mobile one, ASTC newer still. A loader asks before it uploads and a no is a texture left out with a reason, not an ArgumentError out of an allocation. A backend outside this repository has to add the member; the three inside answer from flutter_gpu's capability, the WebGL2 context's extensions, and a constant no for anything compressed.
  • TextureFormatCompression: isCompressed and blockLayout for every block-compressed value, the one source every backend now reads.
  • FakeBackend records the mip chain each upload came with and can be told which formats to refuse.

0.4.0 #

  • A loan that outlives a trim goes back to the allocator. It used to be refiled under its retired pre-resize spec on release, where no acquire would ever match it — parked until the next trim. The pool now hands it straight back, keeps the throw-on-double-release contract, and has tests for the whole shape.

0.3.0 #

  • createCubeTextureFromPixels takes mip levels, which is what image-based lighting needs and what a hand-built chain has to be uploaded through.
  • LayeredShaderLibrary puts an application's own bundle in front of the engine's without replacing it.

0.2.0 #

  • PassEncoder split from CommandEncoder, so a contributor drawing into somebody else's pass cannot end it.
  • A render target pool that releases by identity and waits out the frames in flight, and capability questions a backend answers rather than guesses at.

0.1.0 #

  • The vocabulary an engine writes a frame in: texture and buffer handles, formats, render targets, pipelines, a command encoder and a shader library.

  • No implementation of its own. What it names is what a backend must answer to, and what the engine may assume.

  • SamplerOptions.anisotropy and GraphicsDevice.maxAnisotropy. A floor seen along its length covers a footprint a few texels tall and many wide, and a trilinear sampler picks one level for the whole of it — the level that stops the long axis aliasing blurs the short one. The field is a count of taps along that long axis, one by default so every picture is the bytes it was, checked at construction to sit on a trilinear sampler because that is flutter_gpu's rule and the taps are taken across the chain, and clamped by every backend to what the device answers, so sixteen is a safe thing to ask for. The device getter is there to decide with rather than to guard: the bridge asks it once per level. FakeBackend answers sixteen and can be told otherwise. withAnisotropy copies a sampler with the one field a caller decides at run time.

  • GraphicsDevice.loadShaders: a shader bundle arrives as bytes. The one way a shader reaches a device without being an asset, for an editor that rebuilds a bundle and wants to see it without restarting and for an application that ships a look the engine never heard of and wants it on every backend. ShaderBundle is the container — a header naming the bundle, the SDK it was compiled on and the stages it claims, then one section per backend — with encode/decode checked against each other. LoadedShaderLibrary is what comes back: a ShaderLibrary with refresh, which reparses new bytes in place and keeps the identity of every handle already handed out. ShaderBundleRefused is the one exception a device answers when it will not load a bundle, and it names the bundle: never an empty library, which would fail at the first draw naming a stage rather than the file to rebuild.

  • FakeBackend.loadShaders and FakeLoadedShaderLibrary, which keep the same identity promise so a test of a reload path proves something; FakeBackend.linkedPipelines records every pair linked, in order, so a test can tell a frame that relinked from one that did not.

  • A loaded library lives as long as the device, and loadShaders now says so: there is no release, because the handles it handed out are held by whatever resolved them, so an application whose shaders change loads one bundle and refreshes it in place. LoadedShaderLibrary also says what a pipeline linked before a refresh does until it is dropped — draws the code it had, on every backend — since one backend did not keep that.

  • A refresh that drops a stage in use is refused, naming the stage. The other half of the identity promise, and LoadedShaderLibrary.refresh now says so: a handle is the renderer's for its lifetime, so a bundle that no longer names that stage would leave a live handle over nothing — a stale pipeline on one backend, a link error on another. Every backend and the fake refuse it the same way, before anything is swapped, and the conformance suite holds them to it.

  • ShaderBundle.decode refuses a string field that is not UTF-8 as a ShaderBundleRefused, rather than letting the decoder's own FormatException out as the one exception that was not a refusal.

  • package:flutter3d_hardware/shader_bundle.dart exports the container on its own, with no Flutter behind it: the barrel reaches package:flutter through GraphicsDevice, and the tool that packs a bundle is a dart run script.

  • GraphicsDevice.readback. The pixels of a texture, or a region of it, as the passes submitted before the call left them, answered without stalling on the GPU — a copy queued in order and a future that resolves when the queue reports it done, a frame or two later. readPixels stays for the golden run and the probes, where the caller has stopped drawing and can afford to wait; this is for a caller still drawing that wants last frame's answer while this frame goes on: an exposure meter, an editor's pick. What cannot be read — tile memory, a multisampled target, a cube, a region past the edge — is refused with an ArgumentError by readbackRegionOf, once, so every backend refuses alike. A backend outside this repository has to add the member.

  • A readback is linear eight-bit RGBA or it is refused. readbackFormats names two layouts — r8g8b8a8UNormInt and b8g8r8a8UNormInt, the same four bytes in either order — and readbackRegionOf refuses any other format by name. The contract promises the same bytes on every backend, and a half-float target broke it three ways: on WebGL2 readPixels(RGBA, UNSIGNED_BYTE) of a float attachment is an INVALID_OPERATION that leaves the pack buffer at zeros and the future completing successfully with a black picture; flutter_gpu converted through toByteData; the software rasteriser clamped its floats. A float texture is read through readPixels, or drawn into an eight-bit target first, which is what the exposure meter's luminance pass is for.

  • The sRGB twins are refused too, with a message of their own. They were admitted on the grounds of being eight bits per channel, which is the wrong test: the question is whether three backends hand back the same bytes, and for an encoded texture nothing said they would — flutter_gpu reads through asImage().toByteData(rawRgba), which may hand back the linear values the encoding stands for, WebGL2 hands back what is stored, and the software rasteriser rounds its own floats. Nothing asked: every readback target the engine declares is r8g8b8a8UNormInt, so the two formats were a promise no conformance check ever made. The refusal points at the same texture's UNormInt layout rather than at drawing it into another target, because that is the different fix a different mistake needs.

  • FakeBackend.readback records what was asked — texture and region — and answers zeros unless answerReadback says otherwise, so a test can be the device that saw a dark frame or a particular id.

  • The stencil, whole. StencilState — compare, the three operations, two eight-bit masks — with StencilOperation and StencilFace mirrored from flutter_gpu value for value; PassEncoder.setStencil for one face or both and setStencilReference beside it; the same three fields on PassState, emitted after depth; and DepthTarget saying how its stencil is loaded, stored and cleared. A pass starts with the test off on both faces, whatever the pass before it set.

  • GraphicsDevice.supportsStencil, to ask before configuring a test against an attachment that has none, and TextureFormatStencil.hasStencil for the formats that carry one.

  • StencilState.narrowReference, which is where "eight bits" is decided once instead of three times. Left to themselves a software rasteriser wraps an out-of-range reference, GL clamps it and flutter_gpu forwards it, so the same value meant three things; every backend narrows through this now.

  • BlendState.keepDestination: zero from the source, one from the destination. flutter_gpu has no colour write mask and a discarded fragment writes no stencil, so this is the one way a draw marks the stencil and leaves the picture alone.

  • FakeBackend can be told it has no stencil, and FakePass records the stencil state and reference it was left with.

  • A colour attachment names a face and a level. ColorTarget.face picks a face of a cube in the order the uploads take them, ColorTarget.mipLevel a level below the base, and a pass's initial viewport covers the level. What a reflection probe is drawn into, and the first time anything in the engine renders into a face or a mip.

  • GraphicsDevice.createCubeRenderTarget allocates a cube a pass may draw into, device-private and empty, with a chain of the length asked for and trimmed to what the device will hold; supportsRenderToMip says whether a level below the base can be attached at all, which is the one capability that splits flutter_gpu by platform. FakeBackend records both and answers the capability either way.

0.4.1 #

  • GraphicsDevice.supportsTextureFormat. The question a block-compressed format needs asked and none of the backends was asking: every value of TextureFormat has a name everywhere, and BC is a desktop family, ETC2 a mobile one, ASTC newer still. A loader asks before it uploads and a no is a texture left out with a reason, not an ArgumentError out of an allocation. A backend outside this repository has to add the member; the three inside answer from flutter_gpu's capability, the WebGL2 context's extensions, and a constant no for anything compressed.
  • TextureFormatCompression: isCompressed and blockLayout for every block-compressed value, the one source every backend now reads.
  • FakeBackend records the mip chain each upload came with and can be told which formats to refuse.

0.4.0 #

  • A loan that outlives a trim goes back to the allocator. It used to be refiled under its retired pre-resize spec on release, where no acquire would ever match it — parked until the next trim. The pool now hands it straight back, keeps the throw-on-double-release contract, and has tests for the whole shape.

0.3.0 #

  • createCubeTextureFromPixels takes mip levels, which is what image-based lighting needs and what a hand-built chain has to be uploaded through.
  • LayeredShaderLibrary puts an application's own bundle in front of the engine's without replacing it.

0.2.0 #

  • PassEncoder split from CommandEncoder, so a contributor drawing into somebody else's pass cannot end it.
  • A render target pool that releases by identity and waits out the frames in flight, and capability questions a backend answers rather than guesses at.

0.1.0 #

  • The vocabulary an engine writes a frame in: texture and buffer handles, formats, render targets, pipelines, a command encoder and a shader library.
  • No implementation of its own. What it names is what a backend must answer to, and what the engine may assume.
0
likes
150
points
405
downloads

Documentation

API reference

Publisher

verified publisherpleion.dev

Weekly Downloads

The graphics vocabulary flutter3d is written against: formats, handles, a command encoder and a device. Names no graphics API.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#graphics #gpu #rendering #abstraction

License

MIT (license)

Dependencies

flutter, vector_math

More

Packages that depend on flutter3d_hardware