LCOV - code coverage report
Current view: top level - xenolith/backend/vkgui - XLVkView.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1 0.0 %
Date: 2024-05-12 00:16:13 Functions: 0 1 0.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef XENOLITH_BACKEND_VKGUI_XLVKVIEW_H_
      25             : #define XENOLITH_BACKEND_VKGUI_XLVKVIEW_H_
      26             : 
      27             : #include "XLVk.h"
      28             : #include "XLView.h"
      29             : #include "XLVkSwapchain.h"
      30             : 
      31             : namespace STAPPLER_VERSIONIZED stappler::xenolith::vk {
      32             : 
      33             : class View : public xenolith::View {
      34             : public:
      35             :         struct EngineOptions {
      36             :                 // on some systems, we can not acquire next image until queue operations on previous image is finished
      37             :                 // on this system, we wait on last swapchain pass fence before acquire swapchain image
      38             :                 // swapchain-independent passes is not affected by this option
      39             :                 bool waitOnSwapchainPassFence = false;
      40             : 
      41             :                 // by default, we use vkAcquireNextImageKHR in lockfree manner, but in some cases blocking variant
      42             :                 // is more preferable. If this option is set, vkAcquireNextImageKHR called with UIN64_MAX timeout
      43             :                 // be careful not to block whole view's thread operation on this
      44             :                 bool acquireImageImmediately = false;
      45             : 
      46             :                 // Использовать внешний сигнал вертикальной синхронизации (система должна поддерживать)
      47             :                 // В этом режиме готовые к презентации кадры ожидают сигнала, прежде, чем отправиться
      48             :                 // Также, по сигналу система запрашиваает новый буфер для отрисовки следующего кадра
      49             :                 // Если система не успела подготовить новый кадр - обновление пропускается
      50             :                 bool followDisplayLink = false;
      51             : 
      52             :                 // По умолчанию, FrameEmitter допускает только один кадр определенной RenderQueue в процессе отправки
      53             :                 // (между vkQueueSubmit и освобождением соответсвующей VkFence). Исключение составляют проходы, помеченные как асинхронные
      54             :                 // Если отключить это ограничение, единственным ограничением между vkQueueSubmit останутся внутренние примитивы синхронизации
      55             :                 // В ряде случаев, неограниченная отправка буферов может привести к некорректной работе vkQueueSubmit и блокированию треда на
      56             :                 // этой функции. Рекомендуется сохранять это ограничение. а для полной загрузки GPU использовать асинхронные пре- и пост-проходы
      57             :                 bool enableFrameEmitterBarrier = false;
      58             : 
      59             :                 // Использовать внеэкранный рендеринг для подготовки изображений. В этом режиме презентация нового изображения выполняется
      60             :                 // строго синхронно (см. presentImmediate)
      61             :                 bool renderImageOffscreen = false;
      62             : 
      63             :                 // Не использовать переключение потоков для вывода изображения. Вместо этого, блокироваться на ожидании очереди в текущем потоке
      64             :                 bool presentImmediate = false;
      65             : 
      66             :                 // Запускать следующий кадр только по запросу либо наличию действий в процессе
      67             :                 bool renderOnDemand = true;
      68             :         };
      69             : 
      70             :         virtual ~View();
      71             : 
      72             :         virtual bool init(Application &, const Device &, ViewInfo &&);
      73             : 
      74             :         virtual void threadInit() override;
      75             :         virtual void threadDispose() override;
      76             : 
      77             :         virtual void update(bool displayLink) override;
      78             :         virtual void close() override;
      79             : 
      80             :         virtual void run() override;
      81             :         virtual void runWithQueue(const Rc<RenderQueue> &) override;
      82             : 
      83             :         virtual void onAdded(Device &);
      84             :         virtual void onRemoved();
      85             : 
      86             :         virtual void deprecateSwapchain(bool fast = false) override;
      87             : 
      88             :         virtual bool present(Rc<ImageStorage> &&) override;
      89             :         virtual bool presentImmediate(Rc<ImageStorage> &&, Function<void(bool)> &&scheduleCb) override;
      90             :         virtual void invalidateTarget(Rc<ImageStorage> &&) override;
      91             : 
      92             :         virtual Rc<Ref> getSwapchainHandle() const override;
      93             : 
      94             :         virtual void captureImage(StringView, const Rc<core::ImageObject> &image, AttachmentLayout l) const override;
      95             :         virtual void captureImage(Function<void(const ImageInfoData &info, BytesView view)> &&,
      96             :                         const Rc<core::ImageObject> &image, AttachmentLayout l) const override;
      97             : 
      98             :         void scheduleFence(Rc<Fence> &&);
      99             : 
     100           0 :         virtual uint64_t getUpdateInterval() const { return 0; }
     101             : 
     102             :         virtual void mapWindow();
     103             : 
     104             :         vk::Device *getDevice() const { return _device; }
     105             : 
     106             :         virtual void setReadyForNextFrame() override;
     107             : 
     108             :         virtual void setRenderOnDemand(bool value) override;
     109             :         virtual bool isRenderOnDemand() const override;
     110             : 
     111             : protected:
     112             :         using xenolith::View::init;
     113             : 
     114             : #if SP_REF_DEBUG
     115             :         virtual bool isRetainTrackerEnabled() const override {
     116             :                 return false;
     117             :         }
     118             : #endif
     119             : 
     120             :         enum ScheduleImageMode {
     121             :                 AcquireSwapchainImageAsync,
     122             :                 AcquireSwapchainImageImmediate,
     123             :                 AcquireOffscreenImage,
     124             :         };
     125             : 
     126             :         struct FrameTimeInfo {
     127             :                 uint64_t dt;
     128             :                 uint64_t avg;
     129             :                 uint64_t clock;
     130             :         };
     131             : 
     132             :         virtual bool pollInput(bool frameReady);
     133             : 
     134             :         virtual core::SurfaceInfo getSurfaceOptions() const;
     135             : 
     136             :         void invalidate();
     137             : 
     138             :         void scheduleNextImage(uint64_t windowOffset, bool immediately);
     139             : 
     140             :         // Начать подготовку нового изображения для презентации
     141             :         // Создает объект кадра и начинает сбор данных для его рисования
     142             :         // Создает объект изображения и начинает цикл его захвата
     143             :         // Если режим acquireImageImmediately - блокирует поток до успешного захвата изображения
     144             :         // windowOffset - интервал от текущего момента. когда предполагается презентовать изображение
     145             :         //   Служит для ограничения частоты кадров
     146             :         void scheduleSwapchainImage(uint64_t windowOffset, ScheduleImageMode);
     147             : 
     148             :         // Попытаться захватить изображение для отрисовки кадра. Если задан флаг immediate
     149             :         // или включен режим followDisplayLink - блокирует поток до успешного захвата
     150             :         // В противном случае, если захват не удался - необходимо поробовать позже
     151             :         bool acquireScheduledImageImmediate(const Rc<SwapchainImage> &);
     152             :         bool acquireScheduledImage();
     153             : 
     154             :         void scheduleImage(Rc<SwapchainImage> &&);
     155             :         void onSwapchainImageReady(Rc<SwapchainHandle::SwapchainAcquiredImage> &&);
     156             : 
     157             :         virtual bool recreateSwapchain(core::PresentMode);
     158             :         virtual bool createSwapchain(const core::SurfaceInfo &, core::SwapchainConfig &&cfg, core::PresentMode presentMode);
     159             : 
     160             :         bool isImagePresentable(const core::ImageObject &image, VkFilter &filter) const;
     161             : 
     162             :         // Презентует отложенное подготовленное (кадр завершён) изображение
     163             :         void runScheduledPresent(Rc<SwapchainImage> &&);
     164             : 
     165             :         virtual void presentWithQueue(DeviceQueue &, Rc<ImageStorage> &&);
     166             :         void invalidateSwapchainImage(Rc<ImageStorage> &&);
     167             : 
     168             :         FrameTimeInfo updateFrameInterval();
     169             : 
     170             :         void waitForFences(uint64_t min);
     171             : 
     172             :         virtual void finalize();
     173             : 
     174             :         void updateFences();
     175             : 
     176             :         void clearImages();
     177             : 
     178             :         virtual void schedulePresent(SwapchainImage *, uint64_t);
     179             : 
     180             :         EngineOptions _options;
     181             : 
     182             :         bool _readyForNextFrame = false;
     183             :         bool _blockSwapchainRecreation = false;
     184             :         bool _swapchainInvalidated = false;
     185             :         uint64_t _refId = 0;
     186             :         uint64_t _framesInProgress = 0;
     187             :         uint64_t _fenceOrder = 0;
     188             :         uint64_t _frameOrder = 0;
     189             :         uint64_t _onDemandOrder = 1;
     190             :         uint64_t _scheduledTime = 0;
     191             :         uint64_t _nextPresentWindow = 0;
     192             :         Rc<Surface> _surface;
     193             :         Rc<Instance> _instance;
     194             :         Rc<Device> _device;
     195             :         Rc<SwapchainHandle> _swapchain;
     196             :         String _threadName;
     197             : 
     198             :         Rc<core::ImageStorage> _initImage;
     199             :         Vector<Rc<Fence>> _fences;
     200             : 
     201             :         Vector<Rc<SwapchainImage>> _fenceImages;
     202             :         std::deque<Rc<SwapchainImage>> _scheduledImages;
     203             :         Vector<Rc<SwapchainImage>> _scheduledPresent;
     204             :         Set<SwapchainHandle::SwapchainAcquiredImage *> _requestedSwapchainImage;
     205             :         std::deque<Rc<SwapchainHandle::SwapchainAcquiredImage>> _swapchainImages;
     206             : };
     207             : 
     208             : }
     209             : 
     210             : #endif /* XENOLITH_BACKEND_VKGUI_XLVKVIEW_H_ */

Generated by: LCOV version 1.14