To support dynamic sizing,
capacity is introduced to describe the total size of the buffer, and
size is used to describe the actual size that is used. Various buffers are introduced to support different use cases:
EscherBufferwraps around an
escher::Bufferand is able to grow dynamically when the content grows. It's used to hold data in
StrokePathas input to
SharedBufferis shared between
scenic: it wraps around an
escher::Bufferand the corresponding
fuchsia::ui::gfx::Buffer. It does NOT change size once created.
MeshBufferwraps around two
ShardBuffer's: one for vertex and the other for index. Dynamic sizing is handled here, rather than
SharedBuffer, to avoid duplicate semantics.
MeshBuffer belongs to a
StrokeGroup. It vendors portions of itself to
MeshBuffer::Preserve(). In addition,
MeshBuffer provides the vertex buffer, index buffer, and the bounding box to
scenic, so that
scenic could render the strokes as meshes.
Multi-buffering is required to handle the case where
scenic has not fully rendered the mesh in the last frame but the new
Canvas::Present() comes. It's implemented via a
SharedBuffer pool for efficient buffer usage. Think it in this way:
scenic consumes them. In each frame,
sketchy returns the previous
SharedBuffer's to pool, and grab new ones. The pool monitors the returned
scenic, and once
scenic consumes them, they will be recycled for future use.
Notice that we only recycle
SB2 is consumed for the first time. It's safe to recycle
SB2 starts to get used. However,
SB2 is not yet safe to be recycled because
scenic keeps consuming
SB2 for rendering the following frames (for example, some other
SB triggers a
SB2 has its content unchanged). In that case, we have no signal when
SB2 is finally consumed until a new
SB3 comes and replaces it.