Merge pull request #7465 from sethalves/redo-polyvox-locking

Redo polyvox locking
This commit is contained in:
Clément Brisset 2016-03-25 14:35:27 -07:00
commit 82f22b42e1
4 changed files with 750 additions and 663 deletions

View file

@ -48,6 +48,8 @@ public:
virtual ~RenderablePolyVoxEntityItem(); virtual ~RenderablePolyVoxEntityItem();
void initializePolyVox();
virtual void somethingChangedNotification() { virtual void somethingChangedNotification() {
// This gets called from EnityItem::readEntityDataFromBuffer every time a packet describing // This gets called from EnityItem::readEntityDataFromBuffer every time a packet describing
// this entity comes from the entity-server. It gets called even if nothing has actually changed // this entity comes from the entity-server. It gets called even if nothing has actually changed
@ -114,17 +116,28 @@ public:
virtual void setYPNeighborID(const EntityItemID& yPNeighborID); virtual void setYPNeighborID(const EntityItemID& yPNeighborID);
virtual void setZPNeighborID(const EntityItemID& zPNeighborID); virtual void setZPNeighborID(const EntityItemID& zPNeighborID);
virtual void rebakeMesh();
virtual void updateRegistrationPoint(const glm::vec3& value); virtual void updateRegistrationPoint(const glm::vec3& value);
void setVoxelsFromData(QByteArray uncompressedData, quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize);
void forEachVoxelValue(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize,
std::function<void(int, int, int, uint8_t)> thunk);
void setMesh(model::MeshPointer mesh);
void setCollisionPoints(const QVector<QVector<glm::vec3>> points, AABox box);
PolyVox::SimpleVolume<uint8_t>* getVolData() { return _volData; }
uint8_t getVoxelInternal(int x, int y, int z);
bool setVoxelInternal(int x, int y, int z, uint8_t toValue);
void setVolDataDirty() { withWriteLock([&] { _volDataDirty = true; }); }
private: private:
// The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions // The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
// may not match _voxelVolumeSize. // may not match _voxelVolumeSize.
model::MeshPointer _mesh; model::MeshPointer _mesh;
bool _meshDirty; // does collision-shape need to be recomputed? bool _meshDirty { true }; // does collision-shape need to be recomputed?
mutable QReadWriteLock _meshLock{QReadWriteLock::Recursive}; bool _meshInitialized { false };
NetworkTexturePointer _xTexture; NetworkTexturePointer _xTexture;
NetworkTexturePointer _yTexture; NetworkTexturePointer _yTexture;
@ -135,44 +148,35 @@ private:
static gpu::PipelinePointer _pipeline; static gpu::PipelinePointer _pipeline;
ShapeInfo _shapeInfo; ShapeInfo _shapeInfo;
mutable QReadWriteLock _shapeInfoLock;
PolyVox::SimpleVolume<uint8_t>* _volData = nullptr; PolyVox::SimpleVolume<uint8_t>* _volData = nullptr;
mutable QReadWriteLock _volDataLock{QReadWriteLock::Recursive}; // lock for _volData
bool _volDataDirty = false; // does getMesh need to be called? bool _volDataDirty = false; // does getMesh need to be called?
int _onCount; // how many non-zero voxels are in _volData int _onCount; // how many non-zero voxels are in _volData
bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle, bool _neighborsNeedUpdate { false };
int x, int y, int z) const;
uint8_t getVoxelInternal(int x, int y, int z);
bool setVoxelInternal(int x, int y, int z, uint8_t toValue);
bool updateOnCount(int x, int y, int z, uint8_t toValue); bool updateOnCount(int x, int y, int z, uint8_t toValue);
PolyVox::RaycastResult doRayCast(glm::vec4 originInVoxel, glm::vec4 farInVoxel, glm::vec4& result) const; PolyVox::RaycastResult doRayCast(glm::vec4 originInVoxel, glm::vec4 farInVoxel, glm::vec4& result) const;
// these are run off the main thread // these are run off the main thread
void decompressVolumeData(); void decompressVolumeData();
void decompressVolumeDataAsync();
void compressVolumeDataAndSendEditPacket(); void compressVolumeDataAndSendEditPacket();
void compressVolumeDataAndSendEditPacketAsync(); virtual void getMesh(); // recompute mesh
void getMesh();
void getMeshAsync();
void computeShapeInfoWorker(); void computeShapeInfoWorker();
void computeShapeInfoWorkerAsync();
QSemaphore _threadRunning{1};
// these are cached lookups of _xNNeighborID, _yNNeighborID, _zNNeighborID, _xPNeighborID, _yPNeighborID, _zPNeighborID // these are cached lookups of _xNNeighborID, _yNNeighborID, _zNNeighborID, _xPNeighborID, _yPNeighborID, _zPNeighborID
EntityItemWeakPointer _xNNeighbor; // neighor found by going along negative X axis EntityItemWeakPointer _xNNeighbor; // neighbor found by going along negative X axis
EntityItemWeakPointer _yNNeighbor; EntityItemWeakPointer _yNNeighbor;
EntityItemWeakPointer _zNNeighbor; EntityItemWeakPointer _zNNeighbor;
EntityItemWeakPointer _xPNeighbor; // neighor found by going along positive X axis EntityItemWeakPointer _xPNeighbor; // neighbor found by going along positive X axis
EntityItemWeakPointer _yPNeighbor; EntityItemWeakPointer _yPNeighbor;
EntityItemWeakPointer _zPNeighbor; EntityItemWeakPointer _zPNeighbor;
void clearOutOfDateNeighbors();
void cacheNeighbors(); void cacheNeighbors();
void copyUpperEdgesFromNeighbors(); void copyUpperEdgesFromNeighbors();
void bonkNeighbors(); void bonkNeighbors();
}; };
bool inUserBounds(const PolyVox::SimpleVolume<uint8_t>* vol, PolyVoxEntityItem::PolyVoxSurfaceStyle surfaceStyle,
int x, int y, int z);
#endif // hifi_RenderablePolyVoxEntityItem_h #endif // hifi_RenderablePolyVoxEntityItem_h

View file

@ -64,8 +64,7 @@ PolyVoxEntityItem::PolyVoxEntityItem(const EntityItemID& entityItemID) :
} }
void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) { void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
QWriteLocker(&this->_voxelDataLock); withWriteLock([&] {
assert((int)_voxelVolumeSize.x == _voxelVolumeSize.x); assert((int)_voxelVolumeSize.x == _voxelVolumeSize.x);
assert((int)_voxelVolumeSize.y == _voxelVolumeSize.y); assert((int)_voxelVolumeSize.y == _voxelVolumeSize.y);
assert((int)_voxelVolumeSize.z == _voxelVolumeSize.z); assert((int)_voxelVolumeSize.z == _voxelVolumeSize.z);
@ -97,11 +96,15 @@ void PolyVoxEntityItem::setVoxelVolumeSize(glm::vec3 voxelVolumeSize) {
qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping z of" << _voxelVolumeSize.z << "to max"; qDebug() << "PolyVoxEntityItem::setVoxelVolumeSize clamping z of" << _voxelVolumeSize.z << "to max";
_voxelVolumeSize.z = MAX_VOXEL_DIMENSION; _voxelVolumeSize.z = MAX_VOXEL_DIMENSION;
} }
});
} }
const glm::vec3& PolyVoxEntityItem::getVoxelVolumeSize() const { glm::vec3 PolyVoxEntityItem::getVoxelVolumeSize() const {
QWriteLocker locker(&this->_voxelDataLock); glm::vec3 voxelVolumeSize;
return _voxelVolumeSize; withReadLock([&] {
voxelVolumeSize = _voxelVolumeSize;
});
return voxelVolumeSize;
} }
@ -226,12 +229,16 @@ void PolyVoxEntityItem::debugDump() const {
} }
void PolyVoxEntityItem::setVoxelData(QByteArray voxelData) { void PolyVoxEntityItem::setVoxelData(QByteArray voxelData) {
QWriteLocker(&this->_voxelDataLock); withWriteLock([&] {
_voxelData = voxelData; _voxelData = voxelData;
_voxelDataDirty = true; _voxelDataDirty = true;
});
} }
const QByteArray PolyVoxEntityItem::getVoxelData() const { const QByteArray PolyVoxEntityItem::getVoxelData() const {
QReadLocker(&this->_voxelDataLock); QByteArray voxelDataCopy;
return _voxelData; withReadLock([&] {
voxelDataCopy = _voxelData;
});
return voxelDataCopy;
} }

View file

@ -52,7 +52,7 @@ class PolyVoxEntityItem : public EntityItem {
virtual void debugDump() const; virtual void debugDump() const;
virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize); virtual void setVoxelVolumeSize(glm::vec3 voxelVolumeSize);
virtual const glm::vec3& getVoxelVolumeSize() const; virtual glm::vec3 getVoxelVolumeSize() const;
virtual void setVoxelData(QByteArray voxelData); virtual void setVoxelData(QByteArray voxelData);
virtual const QByteArray getVoxelData() const; virtual const QByteArray getVoxelData() const;
@ -128,12 +128,14 @@ class PolyVoxEntityItem : public EntityItem {
virtual void rebakeMesh() {}; virtual void rebakeMesh() {};
void setVoxelDataDirty(bool value) { withWriteLock([&] { _voxelDataDirty = value; }); }
virtual void getMesh() {}; // recompute mesh
protected: protected:
glm::vec3 _voxelVolumeSize; // this is always 3 bytes glm::vec3 _voxelVolumeSize; // this is always 3 bytes
mutable QReadWriteLock _voxelDataLock;
QByteArray _voxelData; QByteArray _voxelData;
bool _voxelDataDirty; bool _voxelDataDirty; // _voxelData has changed, things that depend on it should be updated
PolyVoxSurfaceStyle _voxelSurfaceStyle; PolyVoxSurfaceStyle _voxelSurfaceStyle;