|
| 1 | +// Copyright 2013 The Flutter Authors. All rights reserved. |
| 2 | +// Use of this source code is governed by a BSD-style license that can be |
| 3 | +// found in the LICENSE file. |
| 4 | + |
| 5 | +import 'dart:ffi'; |
| 6 | +import 'dart:nativewrappers'; |
| 7 | +import 'dart:typed_data'; |
| 8 | + |
| 9 | +/// A reference to a byte range within a GPU-resident [Buffer]. |
| 10 | +class BufferView { |
| 11 | + /// The buffer of this view. |
| 12 | + final HostBuffer buffer; |
| 13 | + |
| 14 | + /// The start of the view, in bytes starting from the beginning of the |
| 15 | + /// [buffer]. |
| 16 | + final int offsetInBytes; |
| 17 | + |
| 18 | + /// The length of the view. |
| 19 | + final int lengthInBytes; |
| 20 | + |
| 21 | + /// Create a new view into a buffer on the GPU. |
| 22 | + const BufferView(this.buffer, |
| 23 | + {required this.offsetInBytes, required this.lengthInBytes}); |
| 24 | +} |
| 25 | + |
| 26 | +/// [HostBuffer] is a [Buffer] which is allocated on the host (native CPU |
| 27 | +/// resident memory) and lazily uploaded to the GPU. A [HostBuffer] can be |
| 28 | +/// safely mutated or extended at any time on the host, and will be |
| 29 | +/// automatically re-uploaded to the GPU the next time a GPU operation needs to |
| 30 | +/// access it. |
| 31 | +/// |
| 32 | +/// This is useful for efficiently chunking sparse data uploads, especially |
| 33 | +/// ephemeral uniform data that needs to change from frame to frame. |
| 34 | +/// |
| 35 | +/// Different platforms have different data alignment requirements for accessing |
| 36 | +/// device buffer data. The [HostBuffer] takes these requirements into account |
| 37 | +/// and automatically inserts padding between emplaced data if necessary. |
| 38 | +base class HostBuffer extends NativeFieldWrapperClass1 { |
| 39 | + /// Creates a new HostBuffer. |
| 40 | + HostBuffer() { |
| 41 | + _initialize(); |
| 42 | + } |
| 43 | + |
| 44 | + /// Wrap with native counterpart. |
| 45 | + @Native<Void Function(Handle)>( |
| 46 | + symbol: 'InternalFlutterGpu_HostBuffer_Initialize') |
| 47 | + external void _initialize(); |
| 48 | + |
| 49 | + /// Append byte data to the end of the [HostBuffer] and produce a [BufferView] |
| 50 | + /// that references the new data in the buffer. |
| 51 | + /// |
| 52 | + /// This method automatically inserts padding in-between emplace calls in the |
| 53 | + /// buffer if necessary to abide by platform-specific uniform alignment |
| 54 | + /// requirements. |
| 55 | + /// |
| 56 | + /// The updated buffer will be uploaded to the GPU if the returned |
| 57 | + /// [BufferView] is used by a rendering command. |
| 58 | + BufferView emplace(ByteData bytes) { |
| 59 | + int resultOffset = _emplaceBytes(bytes); |
| 60 | + return BufferView(this, |
| 61 | + offsetInBytes: resultOffset, lengthInBytes: bytes.lengthInBytes); |
| 62 | + } |
| 63 | + |
| 64 | + @Native<Uint64 Function(Pointer<Void>, Handle)>( |
| 65 | + symbol: 'InternalFlutterGpu_HostBuffer_EmplaceBytes') |
| 66 | + external int _emplaceBytes(ByteData bytes); |
| 67 | +} |
0 commit comments