Skip to content

Cleaning, adding documentation, removing warnings and remove bugs#97

Draft
servantftransperfect wants to merge 1 commit intodevelopfrom
dev/cleanup
Draft

Cleaning, adding documentation, removing warnings and remove bugs#97
servantftransperfect wants to merge 1 commit intodevelopfrom
dev/cleanup

Conversation

@servantftransperfect
Copy link
Copy Markdown
Contributor

This pull request introduces several improvements and refactorings to the qtAliceVision plugin, with a focus on code modernization, thread safety, and improved modularity for the float image viewer. The most significant changes include extracting custom material and node classes for the float image viewer into separate files, enhancing thread safety and type correctness in AsyncFetcher, and updating the build system to reflect new source/header files and shader paths.

Refactoring and Modularity

  • Extracted FloatImageViewerMaterial, FloatImageViewerMaterialShader, and FloatImageViewerNode classes from FloatImageViewer.cpp into their own dedicated files, cleaning up the main file and improving maintainability. ([[1]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-d79c8b4c6c85b777b154b255c9435ca4877d466c2434dca54d984280e7d839d6L4-L7), [[2]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-d79c8b4c6c85b777b154b255c9435ca4877d466c2434dca54d984280e7d839d6L20-L285), Fe933d4cL3R3, [[3]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e58b57ebfda32ca9d6336be78c2f7e63b6100d4980912b051c5d478ac30bc9deR32-R34))

Build System Updates

  • Updated CMakeLists.txt to add new source and header files for the extracted float image viewer components and to adjust shader file paths, ensuring shaders are referenced from the correct directory and not using a prefix. (Fe933d4cL3R3, [[1]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e58b57ebfda32ca9d6336be78c2f7e63b6100d4980912b051c5d478ac30bc9deR32-R34), [[2]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e58b57ebfda32ca9d6336be78c2f7e63b6100d4980912b051c5d478ac30bc9deL79-R93))

Thread Safety and Type Correctness in AsyncFetcher

  • Made AsyncFetcher methods thread-safe by marking mutex and methods as mutable/const where appropriate, and ensured correct locking when accessing shared resources such as _resizeRatio. ([[1]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-82ef2056ce6c71b07dcd940371c1b579ed183c2a7d8e16d5a50362dbe08edd29L134-R134), [[2]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-82ef2056ce6c71b07dcd940371c1b579ed183c2a7d8e16d5a50362dbe08edd29L55-R55), [[3]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-82ef2056ce6c71b07dcd940371c1b579ed183c2a7d8e16d5a50362dbe08edd29L108-R111), [[4]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccR183-R195), [[5]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL224-R230), [[6]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL241-R266))
  • Replaced some unsigned/int/double type usages with more precise and safe types (e.g., std::size_t, float) and improved type casting for clarity and correctness. ([[1]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-c57d2d3ceda7d72504678aa877062f5c3cead58e2e88886b3aaa142d5494773fL61-R77), [[2]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL35-R45), [[3]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL112-R115))

Code Quality and Minor Improvements

  • Improved logic and readability in AsyncFetcher by using .empty() instead of .size() == 0, cleaning up unused includes, and updating comments for clarity. ([[1]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccR6-L10), [[2]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL96-R99), [[3]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL274-R281), [[4]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL283-L284))
  • Added early return in setResizeRatio if the ratio is non-positive, preventing invalid state. ([src/qtAliceVision/AsyncFetcher.cppL35-R45](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL35-R45))

API Consistency

  • Made interface methods like getPrefetching() and getCacheMemory() const for better API consistency and thread safety. ([[1]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-82ef2056ce6c71b07dcd940371c1b579ed183c2a7d8e16d5a50362dbe08edd29L55-R55), [[2]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-82ef2056ce6c71b07dcd940371c1b579ed183c2a7d8e16d5a50362dbe08edd29L108-R111), [[3]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL58-R61), [[4]](https://github.com/alicevision/QtAliceVision/pull/97/files#diff-e2fcc700adda7349eb7db3477f79101d7c78ecb5151c409799f43d4f72a91dccL152-R154))

These changes collectively improve the maintainability, safety, and clarity of the codebase, especially around the float image viewer and asynchronous image fetching components.

This comment was marked as outdated.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 31 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +285 to +297
// commitTextureOperations() runs on the render thread after this function returns
// and may downscale the image to fit GPU limits, changing the texture size.
// Post the updated size back to the GUI thread so the signal fires correctly.
texture->setOnCommit([this](QSize committedSize) {
QMetaObject::invokeMethod(this, [this, committedSize]() {
if (_textureSize != committedSize)
{
_textureSize = committedSize;
_geometryChanged = true;
Q_EMIT textureSizeChanged();
}
}, Qt::QueuedConnection);
});
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The render-thread callback captures a raw this and can outlive the item (e.g., during scene graph teardown), which risks a use-after-free before invokeMethod is even called. Use a QPointer<FloatImageViewer> (or similar guarded handle) inside the callback and return early if it is null, or bind the callback lifetime to a QObject context that is guaranteed to outlive render-thread commits.

Copilot uses AI. Check for mistakes.
Comment thread src/qtAliceVision/FloatTexture.cpp Outdated
Comment on lines +75 to +89
// Work on a local copy so the caller's shared image is never mutated.
FloatImage scaledImage = *_srcImage;
while (_maxTextureSize != -1 && (scaledImage.width() > _maxTextureSize || scaledImage.height() > _maxTextureSize))
{
FloatImage tmp;
aliceVision::image::imageHalfSample(*_srcImage, tmp);
*_srcImage = std::move(tmp);
aliceVision::image::imageHalfSample(scaledImage, tmp);
scaledImage = std::move(tmp);
}
_textureSize = {_srcImage->width(), _srcImage->height()};
_textureSize = {scaledImage.width(), scaledImage.height()};

// Destroy the previous RHI texture before allocating a new one.
_rhiTexture.reset();

const QRhiTexture::Flags texFlags(hasMipmaps() ? QRhiTexture::MipMapped : 0);
_rhiTexture = rhi->newTexture(texFormat, _textureSize, 1, texFlags);
_rhiTexture.reset(rhi->newTexture(texFormat, _textureSize, 1, texFlags));
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This always deep-copies the full source image and always destroys/recreates the GPU texture on each dirty commit. For large float images or during playback, this can be a significant CPU + GPU allocation cost. Consider (1) only copying/downscaling when the image exceeds _maxTextureSize (otherwise upload from _srcImage directly), and (2) reusing _rhiTexture when the size/format/flags are unchanged (only reallocate on size/flag changes).

Copilot uses AI. Check for mistakes.
Comment on lines +23 to +27
int FloatImageViewerMaterial::compare(const QSGMaterial* other) const
{
Q_ASSERT(other && type() == other->type());
return other == this ? 0 : (other > this ? 1 : -1);
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relational pointer comparison (other > this) on unrelated objects is not guaranteed to be well-defined in standard C++. For a stable strict-weak ordering, use std::less<const QSGMaterial*>{}(this, other) (or equivalent) to avoid undefined/unspecified behavior across platforms/compilers.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 23 out of 31 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 282 to +286
texture->setHorizontalWrapMode(QSGTexture::Repeat);
texture->setVerticalWrapMode(QSGTexture::Repeat);
newTextureSize = texture->textureSize();
// commitTextureOperations() runs on the render thread after this function returns
// and may downscale the image to fit GPU limits, changing the texture size.
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When clearBeforeLoad clears _image before an async request completes, updatePaintNode() can enter the _imageChanged path with _image == nullptr, which installs a FloatTexture with no image and later drives _textureSize to (0,0). Downstream aspect-ratio fitting then risks division-by-zero/NaNs. Consider keeping the existing/placeholder texture while loading (or setting an explicit 1x1 placeholder) and guarding geometry calculations until a valid texture size is available.

Copilot uses AI. Check for mistakes.
Comment thread src/qtAliceVision/FloatTexture.cpp Outdated
Comment on lines +84 to +86
// Work on a local copy so the caller's shared image is never mutated.
FloatImage scaledImage = *_srcImage;
while (_maxTextureSize != -1 && (scaledImage.width() > _maxTextureSize || scaledImage.height() > _maxTextureSize))
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commitTextureOperations() always copies the full source image into scaledImage even when no downscaling is required. For large float images this can double memory usage and add a full-frame memcpy on every upload. Consider only creating a copy when the image actually exceeds _maxTextureSize (e.g., work with a const FloatImage* initially, and allocate/copy only inside the downscale loop).

Copilot uses AI. Check for mistakes.
Comment on lines 31 to 37
_sequence = paths;
_currentIndex = 0;

for (unsigned idx = 0; idx < _sequence.size(); idx++)
for (std::size_t idx = 0; idx < _sequence.size(); ++idx)
{
_pathToSeqId[_sequence[idx]] = idx;
_pathToSeqId[_sequence[idx]] = static_cast<unsigned>(idx);
}
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setSequence() rebuilds _pathToSeqId without clearing it first, so paths from a previous sequence can remain mapped and incorrectly update _currentIndex in getFrame(). Clear _pathToSeqId (and ideally reserve) before repopulating it when a new sequence is set.

Copilot uses AI. Check for mistakes.

/**
* @brief Sets the exposure gain factor uploaded to the shader.
* @param gain Gain multiplier (0.0 = no change in the shader's convention).
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The setGain() doc says “0.0 = no change”, but the shader multiplies color by gain, so the neutral value is 1.0 (0.0 would turn the image black). Please correct the documentation to avoid misleading callers.

Suggested change
* @param gain Gain multiplier (0.0 = no change in the shader's convention).
* @param gain Gain multiplier (1.0 = no change).

Copilot uses AI. Check for mistakes.
@servantftransperfect servantftransperfect marked this pull request as draft April 15, 2026 13:50
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants