1 // Copyright 2018 The Fuchsia 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 #pragma once 6 7 #include <fbl/array.h> 8 #include <fbl/intrusive_single_list.h> 9 #include <fbl/unique_ptr.h> 10 #include <fbl/vector.h> 11 #include <lib/fzl/vmo-mapper.h> 12 #include <lib/zx/vmo.h> 13 #include <limits> 14 #include <zircon/types.h> 15 16 namespace fzl { 17 18 // This class is not thread safe. 19 // VMO Pools are collections of VMOs that are used together 20 // and share similiar properties. The VMO pool is intended to be used 21 // by a content producer, as all VMOs in the pool are automatically 22 // mapped to a VMAR. The VMO Pool adds lifecyle management as well, 23 // by keeping track of which vmos are 'locked'. Although this class 24 // does not maintain any vmo handles, mapping the vmos into vmars retains 25 // ownership. 26 // 27 // VMO Pools are intended to act as one backing for BufferCollections. 28 class VmoPool { 29 30 public: 31 // Initializes a VmoPool with a set of vmos. You can pass a vector of vmos, 32 // or a vmo pointer and the number of vmos it should grab. 33 // If successful, returns ZX_OK. 34 zx_status_t Init(const fbl::Vector<zx::vmo>& vmos); 35 zx_status_t Init(const zx::vmo* vmos, size_t num_vmos); 36 37 // Resets the buffer locks and the 'in process' indicator. 38 void Reset(); 39 40 // Finds the next available buffer, and sets that buffer as currently in progress. 41 // Returns ZX_OK if successful, and, if buffer_index != nullptr, stores the 42 // buffer index into buffer_index. 43 // Returns ZX_ERR_NOT_FOUND if no buffers were available or ZX_ERR_BAD_STATE 44 // if a buffer is in the currently in progress state. 45 zx_status_t GetNewBuffer(uint32_t* buffer_index = nullptr); 46 47 // Sets the currently in progress buffer as completed and ready to consume. 48 // The buffer will be locked for CPU reads until BufferRelease is called 49 // with its index. 'Locked' in this context means that GetNewBuffer will 50 // not set this buffer to the current buffer. 51 // Returns ZX_OK if successful, or ZX_ERR_BAD_STATE if no buffer is 52 // currently in progress. 53 // If buffer_index != nullptr, the currently in progress buffer index 54 // will be returned here. 55 zx_status_t BufferCompleted(uint32_t* buffer_index = nullptr); 56 57 // Unlocks the buffer with the specified index and sets it as ready to be 58 // reused. It is permissible to call BufferRelease instead of 59 // BufferCompleted, effectively cancelling use of the current buffer. 60 // Returns ZX_OK if successful, or ZX_ERR_NOT_FOUND if no locked buffer 61 // was found with the given index. If the index is out of bounds, 62 // ZX_ERROR_INVALID_ARGS will be returned. 63 zx_status_t BufferRelease(uint32_t buffer_index); 64 HasBufferInProgress()65 inline bool HasBufferInProgress() const { 66 return current_buffer_ != kInvalidCurBuffer; 67 } 68 69 // Return the size of the current buffer. Returns 0 if no current buffer. 70 uint64_t CurrentBufferSize() const; 71 72 // Return the start address of the current buffer. 73 // Returns nullptr if no current buffer. 74 void* CurrentBufferAddress() const; 75 76 ~VmoPool(); 77 78 private: 79 struct ListableBuffer : public fbl::SinglyLinkedListable<ListableBuffer*> { 80 VmoMapper buffer; 81 }; 82 83 // The sentinel value for no in-progress buffer: 84 static constexpr uint32_t kInvalidCurBuffer = std::numeric_limits<uint32_t>::max(); 85 // The buffer to which we are currently writing. 86 uint32_t current_buffer_ = kInvalidCurBuffer; 87 // VMO backing the buffer. 88 fbl::Array<ListableBuffer> buffers_; 89 // The list of free buffers. 90 fbl::SinglyLinkedList<ListableBuffer*> free_buffers_; 91 }; 92 93 } // namespace fzl 94