Doug Horn | 1427b6a | 2018-12-11 13:19:16 -0800 | [diff] [blame] | 1 | // Copyright 2017 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 | #ifndef LIB_UI_SCENIC_CPP_HOST_MEMORY_H_ |
| 6 | #define LIB_UI_SCENIC_CPP_HOST_MEMORY_H_ |
| 7 | |
| 8 | #include <memory> |
| 9 | #include <utility> |
| 10 | #include <vector> |
| 11 | |
| 12 | #include <lib/zx/vmo.h> |
| 13 | |
| 14 | #include "lib/ui/scenic/cpp/resources.h" |
| 15 | |
| 16 | namespace scenic { |
| 17 | |
| 18 | // Provides access to data stored in a host-accessible shared memory region. |
| 19 | // The memory is unmapped once all references to this object have been released. |
| 20 | class HostData : public std::enable_shared_from_this<HostData> { |
| 21 | public: |
| 22 | // Maps a range of an existing VMO into memory. |
| 23 | HostData(const zx::vmo& vmo, off_t offset, size_t size); |
| 24 | ~HostData(); |
| 25 | |
| 26 | HostData(const HostData&) = delete; |
| 27 | HostData& operator=(const HostData&) = delete; |
| 28 | |
| 29 | // Gets the size of the data in bytes. |
| 30 | size_t size() const { return size_; } |
| 31 | |
| 32 | // Gets a pointer to the data. |
| 33 | void* ptr() const { return ptr_; } |
| 34 | |
| 35 | private: |
| 36 | size_t const size_; |
| 37 | void* ptr_; |
| 38 | }; |
| 39 | |
| 40 | // Represents a host-accessible shared memory backed memory resource in a |
| 41 | // session. The memory is mapped read/write into this process and transferred |
| 42 | // read-only to the scene manager. The shared memory region is retained until |
| 43 | // this object is destroyed. |
| 44 | // TODO(MZ-268): Don't inherit from Memory, so that Memory can have a public |
| 45 | // move constructor. |
| 46 | // TODO(MA-492): The memory is currently not transferred read-only, as we may |
| 47 | // choose to map it as device-local memory on UMA platforms, and Vulkan requires |
| 48 | // a read/write vmo in order to successfully import the memory. |
| 49 | class HostMemory final : public Memory { |
| 50 | public: |
| 51 | HostMemory(Session* session, size_t size); |
| 52 | HostMemory(HostMemory&& moved); |
| 53 | ~HostMemory(); |
| 54 | |
| 55 | HostMemory(const HostMemory&) = delete; |
| 56 | HostMemory& operator=(const HostMemory&) = delete; |
| 57 | |
| 58 | // Gets a reference to the underlying shared memory region. |
| 59 | const std::shared_ptr<HostData>& data() const { return data_; } |
| 60 | |
| 61 | // Gets the size of the data in bytes. |
| 62 | size_t data_size() const { return data_->size(); } |
| 63 | |
| 64 | // Gets a pointer to the data. |
| 65 | void* data_ptr() const { return data_->ptr(); } |
| 66 | |
| 67 | private: |
| 68 | explicit HostMemory(Session* session, |
| 69 | std::pair<zx::vmo, std::shared_ptr<HostData>> init); |
| 70 | |
| 71 | std::shared_ptr<HostData> data_; |
| 72 | }; |
| 73 | |
| 74 | // Represents an image resource backed by host-accessible shared memory bound to |
| 75 | // a session. The shared memory region is retained until this object is |
| 76 | // destroyed. |
| 77 | // TODO(MZ-268): Don't inherit from Image, so that Image can have a public move |
| 78 | // constructor. |
| 79 | class HostImage final : public Image { |
| 80 | public: |
| 81 | HostImage(const HostMemory& memory, off_t memory_offset, |
| 82 | fuchsia::images::ImageInfo info); |
| 83 | HostImage(Session* session, uint32_t memory_id, off_t memory_offset, |
| 84 | std::shared_ptr<HostData> data, fuchsia::images::ImageInfo info); |
| 85 | HostImage(HostImage&& moved); |
| 86 | ~HostImage(); |
| 87 | |
| 88 | HostImage(const HostImage&) = delete; |
| 89 | HostImage& operator=(const HostImage&) = delete; |
| 90 | |
| 91 | // Gets a reference to the underlying shared memory region. |
| 92 | const std::shared_ptr<HostData>& data() const { return data_; } |
| 93 | |
| 94 | // Gets a pointer to the image data. |
| 95 | void* image_ptr() const { |
| 96 | return static_cast<uint8_t*>(data_->ptr()) + memory_offset(); |
| 97 | } |
| 98 | |
| 99 | private: |
| 100 | std::shared_ptr<HostData> data_; |
| 101 | }; |
| 102 | |
| 103 | // Represents a pool of image resources backed by host-accessible shared memory |
| 104 | // bound to a session. All images in the pool must have the same layout. |
| 105 | class HostImagePool { |
| 106 | public: |
| 107 | // Creates a pool which can supply up to |num_images| images on demand. |
| 108 | explicit HostImagePool(Session* session, uint32_t num_images); |
| 109 | ~HostImagePool(); |
| 110 | |
| 111 | HostImagePool(const HostImagePool&) = delete; |
| 112 | HostImagePool& operator=(const HostImagePool&) = delete; |
| 113 | |
| 114 | // The number of images which this pool can manage. |
| 115 | uint32_t num_images() const { return image_ptrs_.size(); } |
| 116 | |
| 117 | // Gets information about the images in the pool, or nullptr if the |
| 118 | // pool is not configured. |
| 119 | const fuchsia::images::ImageInfo* image_info() const { return &image_info_; } |
| 120 | |
| 121 | // Sets the image information for images in the pool. |
| 122 | // Previously created images are released but their memory may be reused. |
| 123 | // If |image_info| is nullptr, the pool reverts to an non-configured state; |
| 124 | // all images are released but the memory is retained for recycling. |
| 125 | // Returns true if the configuration changed. |
| 126 | bool Configure(const fuchsia::images::ImageInfo* image_info); |
| 127 | |
| 128 | // Gets the image with the specified index. |
| 129 | // The |index| must be between 0 and |num_images() - 1|. |
| 130 | // The returned pointer is valid until the image is discarded or the |
| 131 | // pool is reconfigured. Returns nullptr if the pool is not configured. |
| 132 | const HostImage* GetImage(uint32_t index); |
| 133 | |
| 134 | // Discards the image with the specified index but recycles its memory. |
| 135 | // The |index| must be between 0 and |num_images() - 1|. |
| 136 | void DiscardImage(uint32_t index); |
| 137 | |
| 138 | private: |
| 139 | Session* const session_; |
| 140 | |
| 141 | bool configured_ = false; |
| 142 | fuchsia::images::ImageInfo image_info_; |
| 143 | std::vector<std::unique_ptr<HostImage>> image_ptrs_; |
| 144 | std::vector<std::unique_ptr<HostMemory>> memory_ptrs_; |
| 145 | }; |
| 146 | |
| 147 | } // namespace scenic |
| 148 | |
| 149 | #endif // LIB_UI_SCENIC_CPP_HOST_MEMORY_H_ |