blob: 6209422b271b671859431a31c45f3c4ab991841b [file] [log] [blame]
Doug Horn1427b6a2018-12-11 13:19:16 -08001// 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
16namespace 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.
20class 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.
49class 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.
79class 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.
105class 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_