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 "XLCoreDevice.h"
24 :
25 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
26 :
27 32 : Device::Device() { }
28 :
29 32 : Device::~Device() {
30 32 : invalidateObjects();
31 32 : }
32 :
33 32 : bool Device::init(const Instance *instance) {
34 32 : _glInstance = instance;
35 32 : _samplersInfo.emplace_back(SamplerInfo{ .magFilter = Filter::Nearest, .minFilter = Filter::Nearest});
36 32 : _samplersInfo.emplace_back(SamplerInfo{ .magFilter = Filter::Linear, .minFilter = Filter::Linear});
37 32 : return true;
38 : }
39 :
40 0 : void Device::end() {
41 0 : _started = false;
42 :
43 : #if SP_REF_DEBUG
44 : if (isRetainTrackerEnabled()) {
45 : log::debug("Gl-Device", "Backtrace for ", (void *)this);
46 : foreachBacktrace([] (uint64_t id, Time time, const std::vector<std::string> &vec) {
47 : StringStream stream;
48 : stream << "[" << id << ":" << time.toHttp<Interface>() << "]:\n";
49 : for (auto &it : vec) {
50 : stream << "\t" << it << "\n";
51 : }
52 : log::debug("Gl-Device-Backtrace", stream.str());
53 : });
54 : }
55 : #endif
56 0 : }
57 :
58 1216 : Rc<Shader> Device::getProgram(StringView name) {
59 1216 : std::unique_lock<Mutex> lock(_shaderMutex);
60 1216 : auto it = _shaders.find(name);
61 1216 : if (it != _shaders.end()) {
62 0 : return it->second;
63 : }
64 1216 : return nullptr;
65 1216 : }
66 :
67 1216 : Rc<Shader> Device::addProgram(Rc<Shader> program) {
68 1216 : std::unique_lock<Mutex> lock(_shaderMutex);
69 1216 : auto it = _shaders.find(program->getName());
70 1216 : if (it == _shaders.end()) {
71 1216 : _shaders.emplace(program->getName().str<Interface>(), program);
72 1216 : return program;
73 : } else {
74 0 : return it->second;
75 : }
76 1216 : }
77 :
78 0 : Rc<Framebuffer> Device::makeFramebuffer(const QueuePassData *, SpanView<Rc<ImageView>>) {
79 0 : return nullptr;
80 : }
81 :
82 0 : auto Device::makeImage(const ImageInfoData &) -> Rc<ImageStorage> {
83 0 : return nullptr;
84 : }
85 :
86 0 : Rc<Semaphore> Device::makeSemaphore() {
87 0 : return nullptr;
88 : }
89 :
90 0 : Rc<ImageView> Device::makeImageView(const Rc<ImageObject> &, const ImageViewInfo &) {
91 0 : return nullptr;
92 : }
93 :
94 643693 : void Device::addObject(Object *obj) {
95 643693 : std::unique_lock<Mutex> lock(_objectMutex);
96 643733 : _objects.emplace(obj);
97 643733 : }
98 :
99 643701 : void Device::removeObject(Object *obj) {
100 643701 : std::unique_lock<Mutex> lock(_objectMutex);
101 643701 : _objects.erase(obj);
102 643701 : }
103 :
104 0 : void Device::onLoopStarted(Loop &loop) {
105 :
106 0 : }
107 :
108 0 : void Device::onLoopEnded(Loop &) {
109 :
110 0 : }
111 :
112 0 : bool Device::supportsUpdateAfterBind(DescriptorType) const {
113 0 : return false;
114 : }
115 :
116 32 : void Device::clearShaders() {
117 32 : _shaders.clear();
118 32 : }
119 :
120 64 : void Device::invalidateObjects() {
121 64 : Vector<ObjectData> data;
122 :
123 64 : std::unique_lock<Mutex> lock(_objectMutex);
124 96 : for (auto &it : _objects) {
125 32 : if (auto img = dynamic_cast<ImageObject *>(it)) {
126 16 : log::warn("Gl-Device", "Image ", (void *)it, " \"", img->getName(), "\" ((", typeid(*it).name(),
127 32 : ") [rc:", it->getReferenceCount(), "] was not destroyed before device destruction");
128 16 : } else if (auto pass = dynamic_cast<RenderPass *>(it)) {
129 0 : log::warn("Gl-Device", "RenderPass ", (void *)it, " \"", pass->getName(), "\" (", typeid(*it).name(),
130 0 : ") [rc:", it->getReferenceCount(), "] was not destroyed before device destruction");
131 : } else {
132 16 : auto name = it->getName();
133 16 : if (!name.empty()) {
134 0 : log::warn("Gl-Device", "Object ", (void *)it, " \"", name, "\" ((", typeid(*it).name(),
135 0 : ") [rc:", it->getReferenceCount(), "] was not destroyed before device destruction");
136 : } else {
137 16 : log::warn("Gl-Device", "Object ", (void *)it, " (", typeid(*it).name(),
138 32 : ") [rc:", it->getReferenceCount(), "] was not destroyed before device destruction");
139 : }
140 : }
141 : #if SP_REF_DEBUG
142 : log::warn("Gl-Device", "Backtrace for ", (void *)it);
143 : it->foreachBacktrace([] (uint64_t id, Time time, const std::vector<std::string> &vec) {
144 : StringStream stream;
145 : stream << "[" << id << ":" << time.toHttp<Interface>() << "]:\n";
146 : for (auto &it : vec) {
147 : stream << "\t" << it << "\n";
148 : }
149 : log::warn("Gl-Device-Backtrace", stream.str());
150 : });
151 : #endif
152 :
153 32 : auto d = (ObjectData *)&it->getObjectData();
154 :
155 32 : data.emplace_back(*d);
156 :
157 32 : d->callback = nullptr;
158 : }
159 64 : _objects.clear();
160 64 : lock.unlock();
161 :
162 96 : for (auto &_object : data) {
163 32 : if (_object.callback) {
164 32 : _object.callback(_object.device, _object.type, _object.handle, _object.ptr);
165 : }
166 : }
167 :
168 64 : data.clear();
169 64 : }
170 :
171 : }
|