Implement WSI layer swapchain functions for Tizen:
[platform/core/uifw/vulkan-wsi-tizen.git] / wsi / swapchain_base_tizen.hpp
1 #pragma once
2
3 #include <vulkan/vulkan.h>
4
5 #include <layer/private_data.hpp>
6 #include <util/timed_semaphore.hpp>
7 #include <util/custom_allocator.hpp>
8
9 namespace wsi
10 {
11 struct swapchain_image
12 {
13    /* Implementation specific data */
14    void *data{nullptr};
15
16    VkImage image{VK_NULL_HANDLE};
17    VkFence present_fence{VK_NULL_HANDLE};
18 };
19
20 /**
21  * @brief Base swapchain class
22  *
23  * - the swapchain implementations inherit from this class.
24  * - the VkSwapchain will hold a pointer to this class.
25  * - much of the swapchain implementation is done by this class, as the only things needed
26  *   in the implementation are how to create a presentable image and how to present an image.
27  */
28 class swapchain_base
29 {
30 public:
31    swapchain_base(layer::device_private_data &dev_data, const VkAllocationCallbacks *allocator);
32
33    virtual ~swapchain_base()
34    {
35       /* nop */
36    }
37
38    /**
39     * @brief Create swapchain.
40     *
41     * Perform all swapchain initialization, create presentable images etc.
42     */
43    VkResult init(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info);
44
45    /**
46     * @brief Acquires a free image.
47     *
48     * Current implementation blocks until a free image is available.
49     *
50     * @param timeout Unused since we block until a free image is available.
51     *
52     * @param semaphore A semaphore signaled once an image is acquired.
53     *
54     * @param fence A fence signaled once an image is acquired.
55     *
56     * @param pImageIndex The index of the acquired image.
57     *
58     * @return VK_SUCCESS on completion.
59     */
60    VkResult acquire_next_image(uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *image_index);
61
62    /**
63     * @brief Gets the number of swapchain images or a number of at most
64     * m_num_swapchain_images images.
65     *
66     * @param pSwapchainImageCount Used to return number of images in
67     * the swapchain if second parameter is nullptr or represents the
68     * number of images to be returned in second parameter.
69     *
70     * @param pSwapchainImage Array of VkImage handles.
71     *
72     * @return If number of requested images is less than the number of available
73     * images in the swapchain returns VK_INCOMPLETE otherwise VK_SUCCESS.
74     */
75    VkResult get_swapchain_images(uint32_t *swapchain_image_count, VkImage *swapchain_image);
76
77    /**
78     * @brief Submits a present request for the supplied image.
79     *
80     * @param queue The queue to which the submission will be made to.
81     *
82     * @param pPresentInfo Information about the swapchain and image to be presented.
83     *
84     * @param imageIndex The index of the image to be presented.
85     *
86     * @return If queue submission fails returns error of vkQueueSubmit, if the
87     * swapchain has a descendant who started presenting returns VK_ERROR_OUT_OF_DATE_KHR,
88     * otherwise returns VK_SUCCESS.
89     */
90    VkResult queue_present(VkQueue queue, const VkPresentInfoKHR *present_info, const uint32_t image_index);
91
92 protected:
93
94    layer::device_private_data &m_device_data;
95
96    /**
97     * @brief User provided memory allocation callbacks.
98     */
99    const util::allocator m_allocator;
100
101    /**
102     * @brief Vector of images in the swapchain.
103     */
104    util::vector<swapchain_image> m_swapchain_images;
105
106    /**
107     * @brief Handle to the surface object this swapchain will present images to.
108     */
109    VkSurfaceKHR m_surface;
110
111    /**
112     * @brief present mode to use for this swapchain
113     */
114    VkPresentModeKHR m_present_mode;
115
116    /**
117     * @brief Descendant of this swapchain.
118     * Used to check whether or not a descendant of this swapchain has started
119     * presenting images to the surface already. If it has, any calls to queuePresent
120     * for this swapchain will return VK_ERROR_OUT_OF_DATE_KHR.
121     */
122    VkSwapchainKHR m_descendant;
123
124    /**
125     * @brief Ancestor of this swapchain.
126     * Used to check whether the ancestor swapchain has completed all of its
127     * pending page flips (this is required before this swapchain presents for the
128     * first time.
129     */
130    VkSwapchainKHR m_ancestor;
131
132    /**
133     *  @brief Handle to the logical device the swapchain is created for.
134     */
135    VkDevice m_device;
136
137    /**
138     *  @brief Handle to the queue used for signalling submissions
139     */
140    VkQueue m_queue;
141
142    /**
143     * @brief Return the VkAllocationCallbacks passed in this object constructor.
144     */
145    const VkAllocationCallbacks *get_allocation_callbacks()
146    {
147       return m_allocator.get_original_callbacks();
148    }
149
150    /**
151     * @brief Method to wait on all pending buffers to be displayed.
152     */
153    void wait_for_pending_buffers();
154
155    /**
156     * @brief Remove cached ancestor.
157     */
158    void clear_ancestor();
159
160    /**
161     * @brief Remove cached descendant.
162     */
163    void clear_descendant();
164
165    /**
166     * @brief Deprecate this swapchain.
167     *
168     * If an application replaces an old swapchain with a new one, the older swapchain
169     * needs to be deprecated. This method releases all the FREE images and sets the
170     * descendant of the swapchain. We do not need to care about images in other states
171     * at this point since they will be released by the page flip thread.
172     *
173     * @param descendant Handle to the descendant swapchain.
174     */
175    void deprecate(VkSwapchainKHR descendant);
176
177    /**
178     * @brief Platform specific initialization
179     */
180    virtual VkResult init_platform(VkDevice device, const VkSwapchainCreateInfoKHR *swapchain_create_info) = 0;
181
182    /**
183     * @brief Base swapchain teardown.
184     *
185     * Even though the inheritance gives us a nice way to defer display specific allocation
186     * and presentation outside of the base class, it however robs the children classes - which
187     * also happen to do some of their state setting - the oppurtunity to do the last clean up
188     * call, as the base class' destructor is called at the end. This method provides a way to do it.
189     * The destructor is a virtual function and much of the swapchain teardown happens in this method
190     * which gets called from the child's destructor.
191     */
192    void teardown();
193
194    /**
195     * @brief Creates a new swapchain image.
196     *
197     * @param image_create_info Data to be used to create the image.
198     *
199     * @param image Handle to the image.
200     *
201     * @return If image creation is successful returns VK_SUCCESS, otherwise
202     * will return VK_ERROR_OUT_OF_DEVICE_MEMORY or VK_ERROR_INITIALIZATION_FAILED
203     * depending on the error that occured.
204     */
205    virtual VkResult create_image(const VkImageCreateInfo &image_create_info) = 0;
206
207    virtual VkResult acquire_image(uint32_t *image_index) = 0;
208
209    /**
210     * @brief Method to present and image
211     *
212     * @param pending_index Index of the pending image to be presented.
213     *
214     */
215    virtual void present_image(uint32_t pending_index) = 0;
216
217    /**
218     * @brief Transition a presented image to free.
219     *
220     * Called by swapchain implementation when a new image has been presented.
221     *
222     * @param presented_index Index of the image to be marked as free.
223     */
224    void unpresent_image(uint32_t presented_index);
225
226    /**
227     * @brief Method to release a swapchain image
228     *
229     * @param image Handle to the image about to be released.
230     */
231    virtual void destroy_image(void){};
232 };
233
234 } /* namespace wsi */
235