Overte C++ Documentation
OctreePacketData.h
1 //
2 // OctreePacketData.h
3 // libraries/octree/src
4 //
5 // Created by Brad Hefta-Gaub on 11/19/2013.
6 // Copyright 2013 High Fidelity, Inc.
7 //
8 // TO DO:
9 // * add stats tracking for number of unique colors and consecutive identical colors.
10 // (as research for color dictionaries and RLE)
11 //
12 // * further testing of compression to determine optimal configuration for performance and compression
13 //
14 // * improve semantics for "reshuffle" - current approach will work for now and with compression
15 // but wouldn't work with RLE because the colors in the levels would get reordered and RLE would need
16 // to be recalculated
17 //
18 // Distributed under the Apache License, Version 2.0.
19 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
20 //
21 
22 #ifndef hifi_OctreePacketData_h
23 #define hifi_OctreePacketData_h
24 
25 #include <atomic>
26 
27 #include <QByteArray>
28 #include <QString>
29 #include <QUuid>
30 
31 #include <SharedUtil.h>
32 #include <ShapeInfo.h>
33 #include <NLPacket.h>
34 #include <udt/PacketHeaders.h>
35 
36 #include "EntityShape.h"
37 #include "MaterialMappingMode.h"
38 #include "BillboardMode.h"
39 #include "RenderLayer.h"
40 #include "PrimitiveMode.h"
41 #include "WebInputMode.h"
42 #include "PulseMode.h"
43 #include "GizmoType.h"
44 #include "TextEffect.h"
45 #include "TextAlignment.h"
46 #include "TextVerticalAlignment.h"
47 #include "MirrorMode.h"
48 #include "TonemappingCurve.h"
49 #include "AmbientOcclusionTechnique.h"
50 #include "FadeTiming.h"
51 #include "Sampler.h"
52 
53 #include "OctreeConstants.h"
54 #include "OctreeElement.h"
55 
56 using AtomicUIntStat = std::atomic<uintmax_t>;
57 
58 typedef unsigned char OCTREE_PACKET_FLAGS;
59 typedef uint16_t OCTREE_PACKET_SEQUENCE;
60 const uint16_t MAX_OCTREE_PACKET_SEQUENCE = 65535;
61 typedef quint64 OCTREE_PACKET_SENT_TIME;
62 typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE;
63 const int MAX_OCTREE_PACKET_SIZE = udt::MAX_PACKET_SIZE;
64 
65 const unsigned int OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS)
66  + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME);
67 
68 const unsigned int MAX_OCTREE_PACKET_DATA_SIZE =
69  udt::MAX_PACKET_SIZE - (NLPacket::MAX_PACKET_HEADER_SIZE + OCTREE_PACKET_EXTRA_HEADERS_SIZE);
70 const unsigned int MAX_OCTREE_UNCOMRESSED_PACKET_SIZE = MAX_OCTREE_PACKET_DATA_SIZE;
71 
72 const unsigned int MINIMUM_ATTEMPT_MORE_PACKING = sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) + 40;
73 const unsigned int COMPRESS_PADDING = 15;
74 const int REASONABLE_NUMBER_OF_PACKING_ATTEMPTS = 5;
75 
76 const int PACKET_IS_COLOR_BIT = 0;
77 const int PACKET_IS_COMPRESSED_BIT = 1;
78 
80 class LevelDetails {
81  LevelDetails(int startIndex, int bytesOfOctalCodes, int bytesOfBitmasks, int bytesOfColor, int bytesReservedAtStart) :
82  _startIndex(startIndex),
83  _bytesOfOctalCodes(bytesOfOctalCodes),
84  _bytesOfBitmasks(bytesOfBitmasks),
85  _bytesOfColor(bytesOfColor),
86  _bytesReservedAtStart(bytesReservedAtStart) {
87  }
88 
89  friend class OctreePacketData;
90 
91 private:
92  int _startIndex;
93  int _bytesOfOctalCodes;
94  int _bytesOfBitmasks;
95  int _bytesOfColor;
96  int _bytesReservedAtStart;
97 };
98 
101 public:
102  OctreePacketData(bool enableCompression = false, int maxFinalizedSize = MAX_OCTREE_PACKET_DATA_SIZE);
103  ~OctreePacketData();
104 
106  void changeSettings(bool enableCompression = false, unsigned int targetSize = MAX_OCTREE_PACKET_DATA_SIZE);
107 
109  void reset();
110 
113  bool startSubTree(const unsigned char* octcode = NULL);
114 
115  // call to indicate that the current subtree is complete and changes should be committed.
116  void endSubTree();
117 
118  // call rollback the current subtree and restore the stream to the state prior to starting the subtree encoding
119  void discardSubTree();
120 
123 
125  void discardLevel(LevelDetails key);
126 
129  bool endLevel(LevelDetails key);
130 
132  bool appendBitMask(unsigned char bitmask);
133 
136  bool updatePriorBitMask(int offset, unsigned char bitmask);
137 
139  bool reserveBitMask();
140 
143  bool reserveBytes(int numberOfBytes);
144 
146  bool releaseReservedBitMask();
147 
149  bool releaseReservedBytes(int numberOfBytes);
150 
153  bool updatePriorBytes(int offset, const unsigned char* replacementBytes, int length);
154 
156  bool appendColor(colorPart red, colorPart green, colorPart blue);
157 
159  bool appendValue(const nodeColor& color);
160 
162  bool appendValue(uint8_t value);
163 
165  bool appendValue(uint16_t value);
166 
168  bool appendValue(uint32_t value);
169 
171  bool appendValue(quint64 value);
172 
174  bool appendValue(float value);
175 
177  bool appendValue(const glm::vec2& value);
178 
180  bool appendValue(const glm::vec3& value);
181 
183  bool appendValue(const glm::u8vec3& value);
184 
186  bool appendValue(const QVector<glm::vec3>& value);
187 
189  bool appendValue(const QVector<glm::quat>& value);
190 
192  bool appendValue(const QVector<float>& value);
193 
195  bool appendValue(const QVector<bool>& value);
196 
198  bool appendValue(const QVector<QUuid>& value);
199 
201  bool appendValue(const QSet<QString>& value);
202 
204  bool appendValue(const glm::quat& value);
205 
207  bool appendValue(bool value);
208 
210  bool appendValue(const QString& string);
211 
213  bool appendValue(const QUuid& uuid);
214 
216  bool appendValue(const QByteArray& bytes);
217 
219  bool appendValue(const AACube& aaCube);
220 
222  bool appendValue(const QRect& rect);
223 
225  bool appendValue(const Sampler& sampler);
226 
228  bool appendPosition(const glm::vec3& value);
229 
231  bool appendRawData(const unsigned char* data, int length);
232  bool appendRawData(QByteArray data);
233 
236  int getUncompressedByteOffset(int offsetFromEnd = 0) const { return _bytesInUse - offsetFromEnd; }
237 
239  const unsigned char* getFinalizedData();
241  int getFinalizedSize();
242 
244  const unsigned char* getUncompressedData(int byteOffset = 0) { return &_uncompressed[byteOffset]; }
245 
247  int getUncompressedSize() { return _bytesInUse; }
248 
250  void setUncompressedSize(int newSize) { _bytesInUse = newSize; }
251 
253  bool hasContent() const { return (_bytesInUse > 0); }
254 
256  void loadFinalizedContent(const unsigned char* data, int length);
257 
259  bool isCompressed() const { return _enableCompression; }
260 
262  unsigned int getTargetSize() const { return _targetSize; }
263 
265  int getReservedBytes() { return _bytesReserved; }
266 
267  int getBytesAvailable() { return _bytesAvailable; }
268 
270  void debugContent();
271  void debugBytes();
272 
273  static quint64 getCompressContentTime() { return _compressContentTime; }
274  static quint64 getCompressContentCalls() { return _compressContentCalls; }
275  static quint64 getTotalBytesOfOctalCodes() { return _totalBytesOfOctalCodes; }
276  static quint64 getTotalBytesOfBitMasks() { return _totalBytesOfBitMasks; }
277  static quint64 getTotalBytesOfColor() { return _totalBytesOfColor; }
278 
279  static int unpackDataFromBytes(const unsigned char* dataBytes, float& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
280  static int unpackDataFromBytes(const unsigned char* dataBytes, bool& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
281  static int unpackDataFromBytes(const unsigned char* dataBytes, quint64& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
282  static int unpackDataFromBytes(const unsigned char* dataBytes, uint32_t& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
283  static int unpackDataFromBytes(const unsigned char* dataBytes, uint16_t& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
284  static int unpackDataFromBytes(const unsigned char* dataBytes, uint8_t& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
285  static int unpackDataFromBytes(const unsigned char* dataBytes, glm::quat& result) { int bytes = unpackOrientationQuatFromBytes(dataBytes, result); return bytes; }
286  static int unpackDataFromBytes(const unsigned char* dataBytes, EntityShape& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
287  static int unpackDataFromBytes(const unsigned char* dataBytes, ShapeType& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
288  static int unpackDataFromBytes(const unsigned char* dataBytes, MaterialMappingMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
289  static int unpackDataFromBytes(const unsigned char* dataBytes, BillboardMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
290  static int unpackDataFromBytes(const unsigned char* dataBytes, RenderLayer& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
291  static int unpackDataFromBytes(const unsigned char* dataBytes, PrimitiveMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
292  static int unpackDataFromBytes(const unsigned char* dataBytes, WebInputMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
293  static int unpackDataFromBytes(const unsigned char* dataBytes, PulseMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
294  static int unpackDataFromBytes(const unsigned char* dataBytes, GizmoType& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
295  static int unpackDataFromBytes(const unsigned char* dataBytes, TextEffect& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
296  static int unpackDataFromBytes(const unsigned char* dataBytes, TextAlignment& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
297  static int unpackDataFromBytes(const unsigned char* dataBytes, TextVerticalAlignment& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
298  static int unpackDataFromBytes(const unsigned char* dataBytes, MirrorMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
299  static int unpackDataFromBytes(const unsigned char* dataBytes, TonemappingCurve& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
300  static int unpackDataFromBytes(const unsigned char* dataBytes, AmbientOcclusionTechnique& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
301  static int unpackDataFromBytes(const unsigned char* dataBytes, FadeTiming& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); }
302  static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec2& result);
303  static int unpackDataFromBytes(const unsigned char* dataBytes, glm::vec3& result);
304  static int unpackDataFromBytes(const unsigned char* dataBytes, glm::u8vec3& result);
305  static int unpackDataFromBytes(const unsigned char* dataBytes, QString& result);
306  static int unpackDataFromBytes(const unsigned char* dataBytes, QUuid& result);
307  static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<glm::vec3>& result);
308  static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<glm::quat>& result);
309  static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<float>& result);
310  static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<bool>& result);
311  static int unpackDataFromBytes(const unsigned char* dataBytes, QVector<QUuid>& result);
312  static int unpackDataFromBytes(const unsigned char* dataBytes, QSet<QString>& result);
313  static int unpackDataFromBytes(const unsigned char* dataBytes, QByteArray& result);
314  static int unpackDataFromBytes(const unsigned char* dataBytes, AACube& result);
315  static int unpackDataFromBytes(const unsigned char* dataBytes, QRect& result);
316  static int unpackDataFromBytes(const unsigned char* dataBytes, Sampler& result);
317 
318 private:
320  bool append(const unsigned char* data, int length);
321 
323  bool append(unsigned char byte);
324 
325  unsigned int _targetSize;
326  bool _enableCompression;
327 
328  QByteArray _uncompressedByteArray;
329  unsigned char* _uncompressed { nullptr };
330  int _bytesInUse;
331  int _bytesAvailable;
332  int _subTreeAt;
333  int _bytesReserved;
334  int _subTreeBytesReserved; // the number of reserved bytes at start of a subtree
335 
336  bool compressContent();
337 
338  QByteArray _compressedByteArray;
339  unsigned char* _compressed { nullptr };
340  int _compressedBytes;
341  int _bytesInUseLastCheck;
342  bool _dirty;
343 
344  // statistics...
345  int _bytesOfOctalCodes;
346  int _bytesOfBitMasks;
347  int _bytesOfColor;
348  int _bytesOfValues;
349  int _bytesOfPositions;
350  int _bytesOfRawData;
351 
352  int _bytesOfOctalCodesCurrentSubTree;
353 
354  static bool _debug;
355 
356  static AtomicUIntStat _compressContentTime;
357  static AtomicUIntStat _compressContentCalls;
358 
359  static AtomicUIntStat _totalBytesOfOctalCodes;
360  static AtomicUIntStat _totalBytesOfBitMasks;
361  static AtomicUIntStat _totalBytesOfColor;
362  static AtomicUIntStat _totalBytesOfValues;
363  static AtomicUIntStat _totalBytesOfPositions;
364  static AtomicUIntStat _totalBytesOfRawData;
365 };
366 
367 #endif // hifi_OctreePacketData_h
An opaque key used when starting, ending, and discarding encoding/packing levels of OctreePacketData.
Definition: OctreePacketData.h:80
Handles packing of the data portion of PacketType_OCTREE_DATA messages.
Definition: OctreePacketData.h:100
void debugContent()
displays contents for debugging
Definition: OctreePacketData.cpp:708
LevelDetails startLevel()
starts a level marker. returns an opaque key which can be used to discard the level
Definition: OctreePacketData.cpp:241
void changeSettings(bool enableCompression=false, unsigned int targetSize=MAX_OCTREE_PACKET_DATA_SIZE)
change compression and target size settings
Definition: OctreePacketData.cpp:39
bool reserveBytes(int numberOfBytes)
Definition: OctreePacketData.cpp:113
int getUncompressedSize()
the size of the packet in uncompressed form
Definition: OctreePacketData.h:247
static quint64 getTotalBytesOfOctalCodes()
total calls to compress content
Definition: OctreePacketData.h:275
void setUncompressedSize(int newSize)
update the size of the packet in uncompressed form
Definition: OctreePacketData.h:250
int getReservedBytes()
the number of bytes in the packet currently reserved
Definition: OctreePacketData.h:265
bool isCompressed() const
returns whether or not zlib compression enabled on finalization
Definition: OctreePacketData.h:259
bool appendValue(const nodeColor &color)
appends a color to the end of the stream, may fail if new data stream is too long to fit in packet
Definition: OctreePacketData.cpp:302
unsigned int getTargetSize() const
returns the target uncompressed size
Definition: OctreePacketData.h:262
bool startSubTree(const unsigned char *octcode=NULL)
Definition: OctreePacketData.cpp:166
void reset()
reset completely, all data is discarded
Definition: OctreePacketData.cpp:55
bool appendColor(colorPart red, colorPart green, colorPart blue)
appends a color to the end of the stream, may fail if new data stream is too long to fit in packet
Definition: OctreePacketData.cpp:306
void discardLevel(LevelDetails key)
discards all content back to a previous marker key
Definition: OctreePacketData.cpp:246
static quint64 getCompressContentCalls()
total time spent compressing content
Definition: OctreePacketData.h:274
const unsigned char * getUncompressedData(int byteOffset=0)
get pointer to the uncompressed stream buffer at the byteOffset
Definition: OctreePacketData.h:244
void loadFinalizedContent(const unsigned char *data, int length)
load finalized content to allow access to decoded content for parsing
Definition: OctreePacketData.cpp:673
int getFinalizedSize()
get size of the finalized data (it may be compressed or rewritten into optimal form)
Definition: OctreePacketData.cpp:205
int getUncompressedByteOffset(int offsetFromEnd=0) const
Definition: OctreePacketData.h:236
static int unpackDataFromBytes(const unsigned char *dataBytes, float &result)
total bytes of color
Definition: OctreePacketData.h:279
bool hasContent() const
has some content been written to the packet
Definition: OctreePacketData.h:253
bool releaseReservedBitMask()
releases previously reserved space in the stream.
Definition: OctreePacketData.cpp:125
bool appendRawData(const unsigned char *data, int length)
appends raw bytes, might fail if byte would cause packet to be too large
Definition: OctreePacketData.cpp:626
bool appendPosition(const glm::vec3 &value)
appends a position to the end of the stream, may fail if new data stream is too long to fit in packet
Definition: OctreePacketData.cpp:615
static quint64 getTotalBytesOfColor()
total bytes of bitmasks
Definition: OctreePacketData.h:277
bool releaseReservedBytes(int numberOfBytes)
releases previously reserved space in the stream.
Definition: OctreePacketData.cpp:129
bool updatePriorBytes(int offset, const unsigned char *replacementBytes, int length)
Definition: OctreePacketData.cpp:152
bool endLevel(LevelDetails key)
Definition: OctreePacketData.cpp:280
bool updatePriorBitMask(int offset, unsigned char bitmask)
Definition: OctreePacketData.cpp:142
bool reserveBitMask()
reserves space in the stream for a future bitmask, may fail if new data stream is too long to fit in ...
Definition: OctreePacketData.cpp:109
bool appendBitMask(unsigned char bitmask)
appends a bitmask to the end of the stream, may fail if new data stream is too long to fit in packet
Definition: OctreePacketData.cpp:293
const unsigned char * getFinalizedData()
get access to the finalized data (it may be compressed or rewritten into optimal form)
Definition: OctreePacketData.cpp:191
static quint64 getTotalBytesOfBitMasks()
total bytes for octal codes
Definition: OctreePacketData.h:276