Line data Source code
1 : /** 2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev> 3 : 4 : Permission is hereby granted, free of charge, to any person obtaining a copy 5 : of this software and associated documentation files (the "Software"), to deal 6 : in the Software without restriction, including without limitation the rights 7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 : copies of the Software, and to permit persons to whom the Software is 9 : furnished to do so, subject to the following conditions: 10 : 11 : The above copyright notice and this permission notice shall be included in 12 : all copies or substantial portions of the Software. 13 : 14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 : THE SOFTWARE. 21 : **/ 22 : 23 : #include "XLCoreImageStorage.h" 24 : #include "XLCoreLoop.h" 25 : 26 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core { 27 : 28 7498 : ImageStorage::~ImageStorage() { 29 7514 : for (auto &it : _views) { 30 96 : it.second->runReleaseCallback(); 31 : } 32 7418 : _views.clear(); 33 7418 : _image = nullptr; 34 7498 : } 35 : 36 80 : bool ImageStorage::init(Rc<ImageObject> &&image) { 37 80 : _image = move(image); 38 80 : return true; 39 : } 40 : 41 57360 : bool ImageStorage::isStatic() const { 42 57360 : return _image && (_image->getInfo().hints & core::ImageHints::Static) == core::ImageHints::Static; 43 : } 44 : 45 21982 : bool ImageStorage::isCacheable() const { 46 21982 : return !_isSwapchainImage && (!_image || (_image->getInfo().hints & core::ImageHints::DoNotCache) == core::ImageHints::None); 47 : } 48 : 49 21950 : bool ImageStorage::isSwapchainImage() const { 50 21950 : return _isSwapchainImage; 51 : } 52 : 53 0 : void ImageStorage::cleanup() { } 54 : 55 114067 : const Rc<Semaphore> &ImageStorage::getWaitSem() const { 56 114067 : return _waitSem; 57 : } 58 : 59 128855 : const Rc<Semaphore> &ImageStorage::getSignalSem() const { 60 128855 : return _signalSem; 61 : } 62 : 63 7322 : uint32_t ImageStorage::getImageIndex() const { 64 7322 : return _image->getIndex(); 65 : } 66 : 67 22014 : void ImageStorage::rearmSemaphores(Loop &loop) { 68 22014 : if (isStatic()) { 69 0 : return; // no need for sync 70 : } 71 : 72 22014 : if (_waitSem && _waitSem->isWaited()) { 73 : // general case 74 : // successfully waited on this sem 75 : // swap wait/signal sems 76 21870 : auto tmp = move(_waitSem); 77 21870 : _waitSem = nullptr; 78 : 79 21870 : if (_signalSem && _signalSem->isSignaled()) { 80 : // successfully signaled 81 21870 : if (!_signalSem->isWaited()) { 82 21870 : _waitSem = move(_signalSem); 83 : } 84 : } 85 : 86 21870 : _signalSem = move(tmp); 87 21870 : if (!_signalSem->reset()) { 88 0 : _signalSem = nullptr; 89 : } 90 22014 : } else if (!_waitSem) { 91 : // initial case, no wait sem was defined 92 : // try to swap signal sem to wait sem 93 144 : if (_signalSem && _signalSem->isSignaled()) { 94 64 : if (!_signalSem->isWaited()) { 95 : // successfully signaled 96 64 : _waitSem = move(_signalSem); 97 : } 98 : } 99 144 : _signalSem = nullptr; 100 : } else { 101 : // next frame should wait on this waitSem 102 : // signalSem should be unsignaled due frame processing logic 103 0 : _signalSem = nullptr; 104 : } 105 : 106 22014 : if (!_signalSem) { 107 144 : _signalSem = loop.makeSemaphore(); 108 : } 109 : } 110 : 111 0 : void ImageStorage::releaseSemaphore(Semaphore *) { 112 : 113 0 : } 114 : 115 14644 : void ImageStorage::setReady(bool value) { 116 14644 : if (_ready != value) { 117 14644 : _ready = value; 118 14644 : if (value) { 119 7322 : notifyReady(); 120 : } 121 : } 122 14644 : } 123 : 124 0 : void ImageStorage::invalidate() { 125 0 : _invalid = true; 126 0 : notifyReady(); 127 0 : } 128 : 129 6042 : void ImageStorage::waitReady(Function<void(bool)> &&cb) { 130 6042 : if (_invalid || isStatic()) { 131 0 : cb(false); 132 : } 133 6042 : if (!_ready) { 134 6042 : _waitReady.emplace_back(move(cb)); 135 : } else { 136 0 : cb(true); 137 : } 138 6042 : } 139 : 140 86601 : ImageInfoData ImageStorage::getInfo() const { 141 86601 : return _image->getInfo(); 142 : } 143 51446 : Rc<ImageObject> ImageStorage::getImage() const { 144 51446 : return _image; 145 : } 146 : 147 96 : void ImageStorage::addView(const ImageViewInfo &info, Rc<ImageView> &&view) { 148 96 : _views.emplace(info, move(view)); 149 96 : } 150 : 151 79250 : Rc<ImageView> ImageStorage::getView(const ImageViewInfo &info) const { 152 79250 : auto it = _views.find(info); 153 79279 : if (it != _views.end()) { 154 79179 : return it->second; 155 : } 156 96 : return nullptr; 157 : } 158 : 159 0 : Rc<ImageView> ImageStorage::makeView(const ImageViewInfo &) { 160 0 : return nullptr; 161 : } 162 : 163 36626 : void ImageStorage::setLayout(AttachmentLayout l) { 164 36626 : _layout = l; 165 36626 : } 166 16 : AttachmentLayout ImageStorage::getLayout() const { 167 16 : return _layout; 168 : } 169 : 170 7322 : void ImageStorage::notifyReady() { 171 13364 : for (auto &it : _waitReady) { 172 6042 : it(!_invalid); 173 : } 174 7322 : _waitReady.clear(); 175 7322 : } 176 : 177 : }