Overte C++ Documentation
material-networking/src/material-networking/TextureCache.h
1 //
2 // TextureCache.h
3 // libraries/model-networking/src
4 //
5 // Created by Andrzej Kapolka on 8/6/13.
6 // Copyright 2013 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_TextureCache_h
13 #define hifi_TextureCache_h
14 
15 #include <gpu/Texture.h>
16 
17 #include <QImage>
18 #include <QMap>
19 #include <QColor>
20 #include <QMetaEnum>
21 #include <QtCore/QSharedPointer>
22 
23 #include <DependencyManager.h>
24 #include <ResourceCache.h>
25 #include <graphics/TextureMap.h>
26 #include <image/ColorChannel.h>
27 #include <image/TextureProcessing.h>
28 #include <ktx/KTX.h>
29 #include <TextureMeta.h>
30 
31 #include <gpu/Context.h>
32 #include "KTXCache.h"
33 
34 namespace gpu {
35 class Batch;
36 }
37 
39 class Texture {
40 public:
41  gpu::TexturePointer getGPUTexture() const { return _textureSource->getGPUTexture(); }
42  gpu::TextureSourcePointer _textureSource;
43 
44  static std::function<gpu::TexturePointer()> getTextureForUUIDOperator(const QUuid& uuid);
45  static void setUnboundTextureForUUIDOperator(std::function<gpu::TexturePointer(const QUuid&)> textureForUUIDOperator);
46 
47 private:
48  static std::function<gpu::TexturePointer(const QUuid&)> _unboundTextureForUUIDOperator;
49 };
50 
52 class NetworkTexture : public Resource, public Texture {
53  Q_OBJECT
54 
55 public:
56  NetworkTexture(const QUrl& url, bool resourceTexture = false);
57  NetworkTexture(const NetworkTexture& other);
58  ~NetworkTexture() override;
59 
60  QString getType() const override { return "NetworkTexture"; }
61 
62  int getOriginalWidth() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getOriginalWidth() : 0; }
63  int getOriginalHeight() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getOriginalHeight() : 0; }
64  int getWidth() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getWidth() : 0; }
65  int getHeight() const { return _textureSource->getGPUTexture() ? _textureSource->getGPUTexture()->getHeight() : 0; }
66  image::TextureUsage::Type getTextureType() const { return _type; }
67 
68  gpu::TexturePointer getFallbackTexture() const;
69 
70  void refresh() override;
71 
72  Q_INVOKABLE void setOriginalDescriptor(ktx::KTXDescriptor* descriptor) { _originalKtxDescriptor.reset(descriptor); }
73 
74  void setExtra(void* extra) override;
75 
76 signals:
77  void networkTextureCreated(const QWeakPointer<NetworkTexture>& self);
78 
79 public slots:
80  void ktxInitialDataRequestFinished();
81  void ktxMipRequestFinished();
82 
83 protected:
84  void makeRequest() override;
85  void makeLocalRequest();
86  Q_INVOKABLE void handleLocalRequestCompleted();
87 
88  Q_INVOKABLE virtual void downloadFinished(const QByteArray& data) override;
89 
90  bool handleFailedRequest(ResourceRequest::Result result) override;
91 
92  Q_INVOKABLE void loadMetaContent(const QByteArray& content);
93  Q_INVOKABLE void loadTextureContent(const QByteArray& content);
94 
95  Q_INVOKABLE void setImage(gpu::TexturePointer texture, int originalWidth, int originalHeight);
96  void setImageOperator(std::function<gpu::TexturePointer()> textureOperator);
97 
98  Q_INVOKABLE void startRequestForNextMipLevel();
99 
100  void startMipRangeRequest(uint16_t low, uint16_t high);
101  void handleFinishedInitialLoad();
102 
103 private:
104  friend class KTXReader;
105  friend class ImageReader;
106 
107  image::TextureUsage::Type _type { image::TextureUsage::UNUSED_TEXTURE };
108  image::ColorChannel _sourceChannel;
109 
110  enum class ResourceType {
111  META,
112  ORIGINAL,
113  KTX
114  };
115 
116  ResourceType _currentlyLoadingResourceType { ResourceType::META };
117 
118  static const uint16_t NULL_MIP_LEVEL;
119  enum KTXResourceState {
120  PENDING_INITIAL_LOAD = 0,
121  LOADING_INITIAL_DATA, // Loading KTX Header + Low Resolution Mips
122  WAITING_FOR_MIP_REQUEST, // Waiting for the gpu layer to report that it needs higher resolution mips
123  PENDING_MIP_REQUEST, // We have added ourselves to the ResourceCache queue
124  REQUESTING_MIP, // We have a mip in flight
125  FAILED_TO_LOAD
126  };
127 
128  KTXResourceState _ktxResourceState { PENDING_INITIAL_LOAD };
129 
130  // The current mips that are currently being requested w/ _ktxMipRequest
131  std::pair<uint16_t, uint16_t> _ktxMipLevelRangeInFlight{ NULL_MIP_LEVEL, NULL_MIP_LEVEL };
132 
133  ResourceRequest* _ktxHeaderRequest { nullptr };
134  ResourceRequest* _ktxMipRequest { nullptr };
135  QByteArray _ktxHeaderData;
136  QByteArray _ktxHighMipData;
137 
138  uint16_t _lowestRequestedMipLevel { NULL_MIP_LEVEL };
139  uint16_t _lowestKnownPopulatedMip { NULL_MIP_LEVEL };
140 
141  // This is a copy of the original KTX descriptor from the source url.
142  // We need this because the KTX that will be cached will likely include extra data
143  // in its key/value data, and so will not match up with the original, causing
144  // mip offsets to change.
145  ktx::KTXDescriptorPointer _originalKtxDescriptor;
146 
147  int _width { 0 };
148  int _height { 0 };
149  int _maxNumPixels { ABSOLUTE_MAX_TEXTURE_NUM_PIXELS };
150  QByteArray _content;
151 
152  friend class TextureCache;
153 };
154 
155 using NetworkTexturePointer = QSharedPointer<NetworkTexture>;
156 
157 Q_DECLARE_METATYPE(QWeakPointer<NetworkTexture>)
158 
159 
160 class TextureCache : public ResourceCache, public Dependency {
162  Q_OBJECT
163  SINGLETON_DEPENDENCY
164 
165 public:
166 
170  const gpu::TexturePointer& getPermutationNormalTexture();
171 
173  const gpu::TexturePointer& getWhiteTexture();
174 
176  const gpu::TexturePointer& getGrayTexture();
177 
179  const gpu::TexturePointer& getBlueTexture();
180 
182  const gpu::TexturePointer& getBlackTexture();
183 
185  static gpu::TexturePointer getImageTexture(const QString& path, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE);
186 
188  NetworkTexturePointer getTexture(const QUrl& url, image::TextureUsage::Type type = image::TextureUsage::DEFAULT_TEXTURE,
189  const QByteArray& content = QByteArray(), int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS,
190  image::ColorChannel sourceChannel = image::ColorChannel::NONE);
191 
192  std::pair<gpu::TexturePointer, glm::ivec2> getTextureByHash(const std::string& hash);
193  std::pair<gpu::TexturePointer, glm::ivec2> cacheTextureByHash(const std::string& hash, const std::pair<gpu::TexturePointer, glm::ivec2>& textureAndSize);
194 
195  NetworkTexturePointer getResourceTexture(const QUrl& resourceTextureUrl);
196  const gpu::FramebufferPointer& getHmdPreviewFramebuffer(int width, int height);
197  const gpu::FramebufferPointer& getSpectatorCameraFramebuffer();
198  const gpu::FramebufferPointer& getSpectatorCameraFramebuffer(int width, int height);
199  void updateSpectatorCameraNetworkTexture();
200 
201  NetworkTexturePointer getTextureByUUID(const QString& uuid);
202 
203  static const int DEFAULT_SPECTATOR_CAM_WIDTH { 2048 };
204  static const int DEFAULT_SPECTATOR_CAM_HEIGHT { 1024 };
205 
206  void setGPUContext(const gpu::ContextPointer& context) { _gpuContext = context; }
207  gpu::ContextPointer getGPUContext() const { return _gpuContext; }
208 
209 signals:
210  void spectatorCameraFramebufferReset();
211 
212 protected:
213 
214  // Overload ResourceCache::prefetch to allow specifying texture type for loads
215  Q_INVOKABLE ScriptableResource* prefetch(const QUrl& url, int type, int maxNumPixels = ABSOLUTE_MAX_TEXTURE_NUM_PIXELS, image::ColorChannel sourceChannel = image::ColorChannel::NONE);
216 
217  virtual QSharedPointer<Resource> createResource(const QUrl& url) override;
218  QSharedPointer<Resource> createResourceCopy(const QSharedPointer<Resource>& resource) override;
219 
220 private:
221  friend class ImageReader;
222  friend class NetworkTexture;
223  friend class DilatableNetworkTexture;
224  friend class TextureCacheScriptingInterface;
225 
226  TextureCache();
227  virtual ~TextureCache();
228 
229  static const std::string KTX_DIRNAME;
230  static const std::string KTX_EXT;
231 
232  gpu::ContextPointer _gpuContext { nullptr };
233 
234  std::shared_ptr<cache::FileCache> _ktxCache { std::make_shared<KTXCache>(KTX_DIRNAME, KTX_EXT) };
235 
236  // Map from image hashes to texture weak pointers
237  std::unordered_map<std::string, std::pair<std::weak_ptr<gpu::Texture>, glm::ivec2>> _texturesByHashes;
238  std::mutex _texturesByHashesMutex;
239 
240  gpu::TexturePointer _permutationNormalTexture;
241  gpu::TexturePointer _whiteTexture;
242  gpu::TexturePointer _grayTexture;
243  gpu::TexturePointer _blueTexture;
244  gpu::TexturePointer _blackTexture;
245 
246  NetworkTexturePointer _spectatorCameraNetworkTexture;
247  gpu::FramebufferPointer _spectatorCameraFramebuffer;
248 
249  NetworkTexturePointer _hmdPreviewNetworkTexture;
250  gpu::FramebufferPointer _hmdPreviewFramebuffer;
251 };
252 
253 #endif // hifi_TextureCache_h
A texture loaded from the network.
Definition: material-networking/src/material-networking/TextureCache.h:52
virtual Q_INVOKABLE void downloadFinished(const QByteArray &data) override
Definition: material-networking/src/material-networking/TextureCache.cpp:1058
void makeRequest() override
Definition: material-networking/src/material-networking/TextureCache.cpp:533
bool handleFailedRequest(ResourceRequest::Result result) override
Return true if the resource will be retried.
Definition: material-networking/src/material-networking/TextureCache.cpp:676
void refresh() override
Refreshes the resource.
Definition: material-networking/src/material-networking/TextureCache.cpp:1146
Base class for resource caches.
Definition: ResourceCache.h:196
virtual QSharedPointer< Resource > createResource(const QUrl &url)=0
Creates a new resource.
Base class for resources.
Definition: ResourceCache.h:409
Wrapper to expose resources to JS/QML.
Definition: ResourceCache.h:91
A simple object wrapper for an OpenGL texture.
Definition: material-networking/src/material-networking/TextureCache.h:39