build/ci: green builds and tests on all three platforms
Compiler hygiene (all platforms): - Silence warnings across the tree: missing override, -Wreorder ctor init, -Wshadow, -Wsign-compare, missing switch cases, unused functions/captures, Qt 6.11 deprecations (QMouseEvent/QDropEvent accessors, qAsConst, Q_FOREACH over non-shared containers, AA_UseHighDpiPixmaps) and the .bak/ backup tree removal. - Fix regressions from the cleanup: missing clip decls in capi/timeline.cpp, plugin.cpp rename fallout, panel setFocus ambiguity, QGraphicsItem::pos vs event->position(), duplicate k_push_button case, boolean test variable. Windows: - Qt portability: CommandLineParser is_set/add_option, QTimeZone systemTimeZone (QTimeZone::LocalTime is 6.11-only), k_progress_* enum. - Linking: stop adding oakengine to OLIVE_LIBRARIES (import lib plus oakengine-obj caused multiple definitions); add OAKENGINE_STATIC so internal consumers no longer reference __imp_* stubs. - oakengine.ver: export olive::Renderer typeinfo so liboakgl.so can be dlopened (Linux), DynamicRenderer no longer dlcloses backend libraries (crash in RenderManager's dtor calling into unmapped memory). - OTIO runtime: copy DLLs next to every binary on Windows instead of relying on PATH (0xc0000135 in gtest discovery). - Headless GL: the runner only has GDI OpenGL 1.1, killing every render worker. Deploy Mesa llvmpipe as opengl32sw.dll (Qt's software-GL channel) with QT_OPENGL=software, and let QT_OPENGL override the AA_UseDesktopOpenGL default. ExportTask fails fast after 8 consecutive undelivered frames instead of segfaulting or grinding forever; FFmpegEncoder::write_frame tolerates null frames. - Tests: GetTempPathA+PID temp dirs, GetLongPathNameA for 8.3 names, forward-slash normalization when comparing project filenames. Linux: - Install libshaderc-dev so oakvulkan compiles GLSL (Vulkan tests). - Accept UNORM floor-or-round (63/64) in the blit ping-pong test. - Skip MainWindow construction test on the offscreen QPA (cannot paint QOpenGLWidget). Also: oak_cli_transcode gets a 300s ctest timeout, worker logs GL context version and LoadGraph/render_frame stages, and docs/plans/eliminate-event-bridge-issues.md (English translation).
This commit is contained in:
@@ -37,7 +37,7 @@ void AudioWaveformCache::write_waveform(const TimeRange &range,
|
||||
const AudioVisualWaveform *waveform)
|
||||
{
|
||||
// Write each valid range to the segments
|
||||
foreach (const TimeRange &r, valid_ranges) {
|
||||
for (const TimeRange &r : valid_ranges) {
|
||||
if (waveform) {
|
||||
waveforms_->overwrite_sums(*waveform, r.in(), r.in() - range.in(),
|
||||
r.length());
|
||||
|
||||
@@ -18,7 +18,11 @@ DynamicRenderer::DynamicRenderer(const QString &backend, QObject *parent)
|
||||
}
|
||||
|
||||
// Tears down the backend in the reverse order used by Load(): release renderer
|
||||
// resources, destroy the opaque backend object, then unload the shared library.
|
||||
// resources, then destroy the opaque backend object. The shared library itself
|
||||
// is deliberately NOT unloaded: multiple DynamicRenderer instances can wrap the
|
||||
// same backend library, and one instance's dlclose can unmap code that other
|
||||
// instances (or Qt) still reference, producing calls into unmapped memory.
|
||||
// Backend libraries stay mapped until process exit.
|
||||
DynamicRenderer::~DynamicRenderer()
|
||||
{
|
||||
destroy();
|
||||
@@ -27,9 +31,6 @@ DynamicRenderer::~DynamicRenderer()
|
||||
destroy_(handle_);
|
||||
handle_ = nullptr;
|
||||
}
|
||||
if (library_.isLoaded()) {
|
||||
library_.unload();
|
||||
}
|
||||
}
|
||||
|
||||
// Builds the private backend library path for the current platform.
|
||||
|
||||
@@ -373,7 +373,7 @@ bool DiskCacheFolder::delete_least_recent()
|
||||
auto hash_to_delete = disk_data_.begin();
|
||||
|
||||
if (disk_data_.begin() != disk_data_.end()) {
|
||||
for (auto it = disk_data_.begin() + 1; it != disk_data_.end(); it++) {
|
||||
for (auto it = std::next(disk_data_.begin()); it != disk_data_.end(); it++) {
|
||||
if (it->access_time < hash_to_delete->access_time) {
|
||||
hash_to_delete = it;
|
||||
}
|
||||
|
||||
@@ -558,6 +558,8 @@ void OpenGLRenderer::blit(QVariant s, AcceleratedJob &a_job,
|
||||
// over/underflows if the number is large enough, but the likelihood of that is quite low.
|
||||
functions_->glUniform1i(variable_location, value.to_int());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case NodeValue::k_float:
|
||||
// kFloat technically specifies a double but as above, OpenGL doesn't support those.
|
||||
functions_->glUniform1f(variable_location, value.to_double());
|
||||
@@ -828,7 +830,7 @@ void OpenGLRenderer::blit(QVariant s, AcceleratedJob &a_job,
|
||||
vert_vbo.destroy();
|
||||
vao.release();
|
||||
vao.destroy();
|
||||
} catch (std::bad_cast e) {
|
||||
} catch (const std::bad_cast &e) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -975,7 +977,6 @@ GLuint OpenGLRenderer::compile_shader(GLenum type, const QString &code)
|
||||
{
|
||||
const bool is_gles = context_ && context_->isOpenGLES();
|
||||
const int major = context_ ? context_->format().majorVersion() : 0;
|
||||
const int minor = context_ ? context_->format().minorVersion() : 0;
|
||||
const bool is_gles2 = is_gles && (major < 3);
|
||||
const QString gles_preamble =
|
||||
is_gles2 ? QStringLiteral("#version 100\n\n"
|
||||
|
||||
@@ -191,7 +191,7 @@ void PlaybackCache::draw(QPainter *p, const Rational &start, double scale,
|
||||
{
|
||||
p->fillRect(rect, Qt::red);
|
||||
|
||||
foreach (const TimeRange &range, get_validated_ranges()) {
|
||||
for (const TimeRange &range : get_validated_ranges()) {
|
||||
int range_left = rect.left() + (range.in() - start).to_double() * scale;
|
||||
if (range_left >= rect.right()) {
|
||||
continue;
|
||||
@@ -288,11 +288,11 @@ TimeRangeList PlaybackCache::get_invalidated_ranges(TimeRange intersecting) cons
|
||||
|
||||
invalidated.insert(intersecting);
|
||||
|
||||
foreach (const TimeRange &range, validated_) {
|
||||
for (const TimeRange &range : validated_) {
|
||||
invalidated.remove(range);
|
||||
}
|
||||
|
||||
foreach (const TimeRange &range, passthroughs_) {
|
||||
for (const TimeRange &range : passthroughs_) {
|
||||
invalidated.remove(range);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,9 +69,9 @@ static int
|
||||
get_ofx_av_pixel_format(const OFX::Host::ImageEffect::Image &image,
|
||||
int *bytes_per_pixel)
|
||||
{
|
||||
const std::string &depth =
|
||||
[[maybe_unused]] const std::string &depth =
|
||||
image.getStringProperty(kOfxImageEffectPropPixelDepth);
|
||||
const std::string &components =
|
||||
[[maybe_unused]] const std::string &components =
|
||||
image.getStringProperty(kOfxImageEffectPropComponents);
|
||||
|
||||
olive::core::PixelFormat pixel_format = olive::core::PixelFormat::invalid;
|
||||
@@ -289,7 +289,7 @@ get_destination_av_pixel_format(const olive::VideoParams ¶ms);
|
||||
|
||||
// 作用:读取 clip 偏好(像素深度与分量)并更新 VideoParams。
|
||||
// Purpose: Apply clip preferences (depth/components) into VideoParams.
|
||||
static bool
|
||||
[[maybe_unused]] static bool
|
||||
apply_clip_preferences_to_params(const OFX::Host::ImageEffect::ClipInstance &clip,
|
||||
olive::VideoParams *params)
|
||||
{
|
||||
@@ -298,7 +298,7 @@ apply_clip_preferences_to_params(const OFX::Host::ImageEffect::ClipInstance &cli
|
||||
}
|
||||
|
||||
olive::core::PixelFormat format = olive::core::PixelFormat::invalid;
|
||||
const std::string &depth = clip.getPixelDepth();
|
||||
[[maybe_unused]] const std::string &depth = clip.getPixelDepth();
|
||||
if (depth == kOfxBitDepthByte) {
|
||||
format = olive::core::PixelFormat::u8;
|
||||
} else if (depth == kOfxBitDepthShort) {
|
||||
@@ -310,7 +310,7 @@ apply_clip_preferences_to_params(const OFX::Host::ImageEffect::ClipInstance &cli
|
||||
}
|
||||
|
||||
int channels = 0;
|
||||
const std::string &components = clip.getComponents();
|
||||
[[maybe_unused]] const std::string &components = clip.getComponents();
|
||||
if (components == kOfxImageComponentRGBA) {
|
||||
channels = 4;
|
||||
} else if (components == kOfxImageComponentRGB) {
|
||||
@@ -359,6 +359,8 @@ static const char *ofx_depth_from_pixel_format(olive::core::PixelFormat format)
|
||||
return kOfxBitDepthShort;
|
||||
case olive::core::PixelFormat::f16:
|
||||
return kOfxBitDepthHalf;
|
||||
default:
|
||||
break;
|
||||
case olive::core::PixelFormat::f32:
|
||||
return kOfxBitDepthFloat;
|
||||
case olive::core::PixelFormat::invalid:
|
||||
@@ -460,7 +462,7 @@ static bool params_convertible(const olive::VideoParams ¶ms)
|
||||
|
||||
// 作用:在 clip 偏好无效时,选择一个插件支持的输出格式。
|
||||
// Purpose: Pick a supported output format when clip preferences are invalid.
|
||||
static void
|
||||
[[maybe_unused]] static void
|
||||
choose_supported_output_params(const OFX::Host::ImageEffect::Instance &instance,
|
||||
const OFX::Host::ImageEffect::ClipInstance &clip,
|
||||
const olive::VideoParams &preferred,
|
||||
@@ -522,7 +524,7 @@ convert_texture_for_params(olive::TexturePtr src,
|
||||
|
||||
// 作用:根据插件能力与偏好选择输入格式并执行转换。
|
||||
// Purpose: Select a supported input format and convert texture for the clip.
|
||||
static olive::TexturePtr
|
||||
[[maybe_unused]] static olive::TexturePtr
|
||||
convert_texture_for_clip(const OFX::Host::ImageEffect::Instance &instance,
|
||||
const OFX::Host::ImageEffect::ClipInstance &clip,
|
||||
olive::TexturePtr src,
|
||||
@@ -670,7 +672,7 @@ convert_texture_for_clip(const OFX::Host::ImageEffect::Instance &instance,
|
||||
|
||||
// 作用:从 OFX Image 复制数据到 AVFrame(按图像属性推导格式)。
|
||||
// Purpose: Copy OFX Image data into an AVFrame with inferred format.
|
||||
static olive::AVFramePtr
|
||||
[[maybe_unused]] static olive::AVFramePtr
|
||||
create_avframe_from_ofx_image(OFX::Host::ImageEffect::Image &image)
|
||||
{
|
||||
void *data_ptr = image.getPointerProperty(kOfxImagePropData);
|
||||
@@ -1323,10 +1325,9 @@ static void log_image_props(const char *label,
|
||||
int rod[4] = { 0, 0, 0, 0 };
|
||||
image->getIntPropertyN(kOfxImagePropBounds, bounds, 4);
|
||||
image->getIntPropertyN(kOfxImagePropRegionOfDefinition, rod, 4);
|
||||
const int row_bytes = image->getIntProperty(kOfxImagePropRowBytes);
|
||||
const std::string &depth =
|
||||
[[maybe_unused]] const std::string &depth =
|
||||
image->getStringProperty(kOfxImageEffectPropPixelDepth);
|
||||
const std::string &components =
|
||||
[[maybe_unused]] const std::string &components =
|
||||
image->getStringProperty(kOfxImageEffectPropComponents);
|
||||
/*qWarning().noquote()
|
||||
<< "OFX image props" << label
|
||||
@@ -1370,7 +1371,7 @@ static void schedule_error_dialog_and_undo(const QString &message)
|
||||
}
|
||||
}
|
||||
|
||||
static olive::AVFramePtr download_texture_to_frame(const olive::TexturePtr &tex)
|
||||
[[maybe_unused]] static olive::AVFramePtr download_texture_to_frame(const olive::TexturePtr &tex)
|
||||
{
|
||||
if (!tex || tex->is_dummy() || !tex->renderer()) {
|
||||
return nullptr;
|
||||
@@ -1425,7 +1426,7 @@ select_best_plugin_input_format(const OFX::Host::ImageEffect::Descriptor &desc)
|
||||
bool supports_f16 = false;
|
||||
|
||||
for (int i = 0; i < dim; ++i) {
|
||||
const std::string &depth =
|
||||
[[maybe_unused]] const std::string &depth =
|
||||
props.getStringProperty(kOfxImageEffectPropSupportedPixelDepths, i);
|
||||
if (depth == kOfxBitDepthFloat) {
|
||||
supports_f32 = true;
|
||||
@@ -1541,8 +1542,8 @@ void olive::plugin::PluginRenderer::render_plugin(
|
||||
if (!tex->is_dummy() && tex->renderer()) {
|
||||
return true;
|
||||
}
|
||||
AVFramePtr frame = tex->frame();
|
||||
return frame && frame->data(0);
|
||||
AVFramePtr av_frame = tex->frame();
|
||||
return av_frame && av_frame->data(0);
|
||||
};
|
||||
std::map<std::string, TexturePtr> input_textures;
|
||||
std::map<std::string, OliveClipInstance *> input_clips;
|
||||
@@ -1817,12 +1818,10 @@ void olive::plugin::PluginRenderer::render_plugin(
|
||||
}
|
||||
// Diagnostic: peek at first few pixels
|
||||
void *img_data = output_image->getPointerProperty(kOfxImagePropData);
|
||||
bool img_black = true;
|
||||
if (img_data) {
|
||||
float *f = static_cast<float *>(img_data);
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
if (f[i] != 0.0f) {
|
||||
img_black = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ void RenderJobTracker::insert(const TimeRange &range, JobTime job_time)
|
||||
|
||||
void RenderJobTracker::insert(const TimeRangeList &ranges, JobTime job_time)
|
||||
{
|
||||
foreach (const TimeRange &r, ranges) {
|
||||
for (const TimeRange &r : ranges) {
|
||||
insert(r, job_time);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user