Commit Graph
26 Commits
Author SHA1 Message Date
Mike-Solar 712badbaa7 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).
2026-08-04 21:34:31 +08:00
Mike-Solar 5006382790 ci: oakvulkan keeps full sources on Windows
vulkanrenderer.cpp is NOT part of oakengine-obj (unlike
openglrenderer.cpp), so the entry-point-only treatment from the
previous change left VulkanRenderer symbols undefined. Compile the
renderer into the plugin and link oakengine-obj + olive-version-obj.
2026-08-03 14:38:38 +08:00
Mike-Solar 960d6361d5 ci: make Windows render plugins entry-point-only (fix duplicate symbols)
oakengine-obj already contains openglrenderer.cpp and its moc output;
compiling them again into oakgl.dll plus embedding oakengine-obj caused
duplicate definitions and a stray k_app_version reference. On Windows
the plugins now compile only the C entry point and link oakengine-obj +
olive-version-obj.
2026-08-03 13:52:28 +08:00
Mike-Solar 1af7ab7838 ci: engine tests use dllexport-consistent macros on Windows; run Linux tests under Xvfb
- make_oakengine_gtest embeds oakengine-obj; test code must see
  OAKENGINE_API as dllexport too (OAKENGINE_BUILD), otherwise MinGW
  resolves nothing against __imp_* stubs
- the render worker intentionally drops QT_QPA_PLATFORM=offscreen and
  needs a real display for its GL context; run the Linux ctest and the
  filtered gtest steps under xvfb-run
2026-08-03 13:32:18 +08:00
Mike-Solar 631f9e5bd1 ci: link render backend plugins against oakengine-obj on Windows; switch runners
- liboakengine.dll does not export engine-internal C++ symbols
  (olive::Renderer, FileFunctions, VideoParams, Texture), so oakgl.dll
  failed to link on Windows. Embed oakengine-obj instead (same pattern
  as the engine tests); MinGW's name-based RTTI keeps cross-DLL casts
  working.
- ci.yml: move to warp runners
2026-08-03 13:13:42 +08:00
Mike-Solar 835d47244c ci: sweep remaining QLatin1String::toUtf8; embed version obj in oakengine.dll
- pointer.cpp/transition.cpp: same Qt 6.4 incompatibility as import.cpp
- Windows: DLLs cannot have undefined symbols, so the
  executable-provides-k_app_version trick does not link; embed
  olive-version-obj into oakengine on WIN32 (each module keeps its own
  copy)
2026-08-03 12:48:27 +08:00
Mike-Solar 824e352da1 ci: declare all oakengine handle types opaque for Qt metatypes; defer gtest discovery on Windows
- Linux GCC rejects QMetaType instantiation over incomplete types
  (static_assert(sizeof(T))); Q_DECLARE_OPAQUE_POINTER every opaque
  OakEngine* handle in the public headers so QList<OakEngineTask*> etc
  compile
- Windows: gtest discovery ran the fresh exe before the DLLs were next
  to it; use DISCOVERY_MODE PRE_TEST on WIN32 and copy the DLLs for
  ctest time
2026-08-02 17:44:51 +08:00
Mike-Solar d57c812fa6 ci: fix three platform-specific build failures
- Linux: Qt6 metatype static_assert requires complete types; declare
  OakEngineBlock with Q_DECLARE_OPAQUE_POINTER in the public header
  (outside extern "C")
- Windows: gtest discovery runs the freshly linked test exe at build
  time and it cannot find the DLLs (0xc0000135); copy oakcore/oakengine/
  ffmpeg_bridge DLLs next to the test binaries on WIN32
- macOS: Imath header mixing between otio-install's stale bundled Imath
  and Homebrew's Imath broke ImathBox.h (V2h undeclared); bump the OTIO
  cache to v2 and drop bundled Imath headers so the system one is the
  only set in play
2026-08-02 16:24:16 +08:00
Mike-Solar 5f8232a594 ci: fix macOS/Linux configure (oakgl) and Windows MSYS2 git
- OAK_ENABLE_DYNAMIC_RENDER_BACKEND now defaults ON; it was previously
  undefined (OFF) unless passed, so CI configure failed on the
  unconditional oakgl target references in app/worker/tests
- add git to the MSYS2 package list in ci.yml and cd.yml; the OTIO
  build step runs git clone in the msys2 shell, where git is not
  installed by default
2026-08-02 15:32:07 +08:00
Mike-Solar 8399d04b44 build: raise gtest discovery timeout to 60s
Freshly linked binaries can exceed the 5s default on first run
(dyld cold cache + Qt/OCIO init).
2026-08-01 19:14:31 +08:00
Mike-Solar 66d761b4b7 R8: finish app/ pure C ABI migration (P3-P9) and make OTIO required
- app/ no longer includes engine C++ headers nor holds engine C++ types:
  engine access goes through the oakengine C ABI plus C++ wrappers
  (oakutil/oaknode.h, oakutil/oakvideo.h) and app-local mirror types
  (tooltypes, trackreferencehandle, timelinecommonapp, keyframetypes,
  subtitleapp, serializedlayoutinfoapp, nodevaluehandle, sliderdisplaytypeapp)
- engine: new C ABI functions for block/track/clip/transition navigation
  and predicates, links, caches, waveform/playback, disk folder,
  sequence_track_list, node_free, footage_is_valid, block_get_track,
  get_brush; loadotio/saveotio ported to the current engine API
- OTIO is now a required dependency: CI and CD build it on every
  platform, FindOpenTimelineIO fixed for OTIO 0.16/0.19 (the old deps
  include requirement silently disabled OTIO everywhere), runtime
  libraries are bundled into packages and copied next to macOS binaries
  (oak_copy_otio_runtime)
- fix ProjectViewModel drag&drop mime read/write size mismatch (segfault)
- unify color label naming (k_olive -> "Oak") in the app-side mirror
- docs: OTIO required, FFmpeg minimum corrected to 6.0 (en/zh)
- gtest suite: 1925 passed, 0 failed
2026-07-31 22:46:52 +08:00
Mike-Solar 18aed979a2 build: fix macOS build issues blocking app compilation
- engine: liboakengine.dylib intentionally leaves olive::k_app_version
  to the final executable (olive-version-obj); whitelist that symbol
  with -U on Apple, where undefined symbols in dylibs are an error
  (ELF allows them by default).
- app/common/configwrapper.h: only declare the int64_t/uint64_t
  conversion/assignment overloads on Linux LP64, where they differ
  from qint64/quint64; elsewhere both are long long and the extra
  overloads are redeclarations.
2026-07-27 17:14:56 +08:00
Mike-Solar a84e75ef47 change: UI and migrate to gtest 2026-07-27 05:27:32 +08:00
Mike-Solar eb634b53ef R7: pure C ABI display boundary + engine visibility closure
R7-A (Qwen 3.8 Max): oakengine/display.h rewritten to the POD contract
from r7-pure-abi-plan.md - oak_video_params everywhere, opaque
texture/frame handles with retain/free protocol (engine-heap control
blocks), OakSharedBuffer refcounted wrapper for the QVariant playback
path. All TexturePtr/FramePtr gone from app (47 sites).

R7-B (Qwen 3.8 Max): liboakengine.so exports 3486 -> 19 C++ symbols
(version script oakengine.ver: oakengine_* plus the documented
oakgl/oakvulkan dlopen plugin ABI). oakengine-obj OBJECT library feeds
both the shared lib and the test binaries (-rdynamic so dlopen'd
backends resolve engine objects).

Fix (Kimi K3): producer/consumer type mismatch - viewerdisplay
unpacks OakSharedBufferPtr but viewer.cpp pushed raw void* handles,
so no frame ever reached the display widget (all 5 vulkan viewer
tests timed out with 'never received a texture'). Producers now wrap
with oak_make_shared_frame / oak_make_shared_texture(retain).

Verified: build 0 errors, ctest 45/45, nm U _ZN5olive = 0 in
oak-editor/oak-render-worker/oak-cli, 19 exported C++ symbols in
liboakengine.so (all documented plugin ABI).
2026-07-27 00:54:46 +08:00
Mike-Solar e9f173916f engine: complete C ABI facade (liboakengine oakengine_* surface)
The full pure-C facade used by the app: node/project/timeline/viewer/
undo/task/events/serializer/playback/preview/renderer/gizmo/color/
audio/footage/proxy/encoding/exporter/config/disk/ipc/plugin/worker
families, plus undo-group semantics, display renderer handles,
NodeFactory accessors, and per-family pure-C engine tests.
2026-07-26 22:43:00 +08:00
Mike-Solar d63131cb12 engine: add the playback family to the facade 2026-07-20 17:46:49 +08:00
Mike-Solar bb17c59c0f engine: add the preview family to the C ABI facade
- clip-level loop mode (off/loop/clamp), undoable
- per-channel audio levels as one-frame RMS at a timestamp
- waveform min/max buckets over a footage range, rendered on demand
- two real fixes uncovered by this family: conform completion signals
  were starved by msleep-only waits (audio renders always came back
  empty), and incomplete tickets from conform-pending renders are now
  retried until the conform is ready
2026-07-20 09:28:47 +08:00
Mike-Solar eaa301b755 engine: add the keyframe family to the node facade
- keyframed state, count, read (time in sequence timebase + mapped
  values), add/remove, easing read/write (linear/bezier/hold with
  control points), and clear - all undoable with full undo/redo
  assertions
- easing set commands are minimal capi-local UndoCommands matching
  the app-layer semantics (engine has none of its own); same-time
  duplicates are rejected with E_STATE instead of hitting the engine's
  debug assert
2026-07-20 08:31:24 +08:00
Mike-Solar e82011b0ee engine: add the node graph family to the C ABI facade
- project node enumeration, type/name/label metadata, input
  introspection (id, mapped value type, connection state)
- typed parameter read/write for the eight common NodeValue kinds
  (int/float/bool/rational/color/vec2-4/combo/string), undoable via
  NodeParamSetSplitStandardValueCommand - the split-track value path,
  chosen after proving the standard-value command stores whole
  variants into a single component track
- graph operations (add/remove/connect/disconnect) reusing the
  engine's undo commands, all covered by undo/redo assertions
2026-07-20 08:16:43 +08:00
Mike-Solar b9b5ad09f7 engine: add the export family to the C ABI facade; mp4 transcode
- oakengine_export_render drives ExportTask synchronously (offline
  render + encode) with a progress callback, codec probing, and a
  thread-local error channel; exporter.h keeps clear of the visibility
  macro header
- oak-cli transcode now defaults to mp4 (H.264/AAC) with --format ppm
  keeping the raw output path
- two real concurrency bugs found by the facade's own test: ExportTask
  deadlocks when start()ed synchronously (queued conform handshake
  needs an event loop), and the progress callback must be captured by
  value because it fires on the task thread
2026-07-20 07:34:21 +08:00
Mike-Solar c1ee784600 engine: timeline edit primitives and oak-cli transcode
- oakengine_sequence_add_track and add_footage_clip are the facade's
  first editing primitives: undoable track creation and clip placement
  with full range validation, clip enumeration, and gap filtering
- oak-cli transcode closes the loop: media file -> import -> clip ->
  render, producing scaled PPM frames and a WAV from just the C ABI
- engine fix uncovered by transcode: the render worker used an invalid
  empty AudioParams for IPC render frames, crashing any sequence that
  contains audio; it now derives them from the rendered node itself
- sequence_new hardens its defaults against missing audio config keys
2026-07-20 06:33:14 +08:00
Mike-Solar 1a7029fd8f engine: add the footage family to the C ABI facade; oak-cli probe
- oakengine_footage_probe inspects media without a project (decoder
  probe): stream counts, per-stream video info (dimensions, rate,
  duration, color tags, interlacing), audio info, duration, decoder
  name, source start time; thread_local last_error for the NULL-handle
  failure paths
- oakengine_project_import_footage adds probed footage to a project
  through the same undoable command path as the app
- oak-cli probe prints decoder/duration/per-stream details and runs as
  a ctest everywhere (no GL)
- dual ownership documented: probe handles are owned, imported footage
  is borrowed from its project
2026-07-20 06:03:16 +08:00
Mike-Solar b26ffb7d64 engine: add the renderer family to the C ABI facade
- oakengine_renderer_create/set_mode/last_error, render_frame (sync,
  60s timeout, CPU frames via the existing worker pool),
  render_audio (planar float), cancel; frames and audio buffers are
  owned handles with borrowed data pointers
- output colorspace names map to OCIO display transforms, with
  graceful fallback to reference-space output
- oakengine_renderer_test: parameter validation and error paths need
  no GL and always run; render assertions gate on
  DynamicRenderer backend availability and SKIP cleanly otherwise
- fix a facade bug found by its own test: wait_for_ticket leaked a
  connected lambda capturing a stack reference, which a subsequent
  cancelled ticket could fire into reused stack memory
2026-07-20 05:26:42 +08:00
Mike-Solar 5db7aac058 engine: add init/project/timeline families to the C ABI facade
- oakengine_init/shutdown with HEADLESS/RENDER flags: headless boots
  Config, NodeFactory, ColorManager, task/conform/proxy/frame/disk
  managers and the serializer (plus an offscreen QGuiApplication that
  Qt requires for QAction); RENDER adds RenderManager. Idempotent and
  upgradable, no UI anywhere
- oakengine_project_* (17): create/load/save, modified state, name,
  footage enumeration with online check, undo/redo, sequence access
- oakengine_sequence_* (13): name, length (seconds and rational),
  frame rate, per-type track counts, playhead (timestamp and seconds),
  work area, markers; sequences are borrowed handles owned by their
  project
- pure-C oakengine_init_test covers init idempotency, save/load
  round-trip through a real fixture project, footage online checks,
  timeline parameters, and NULL/bounds safety - no GL required
2026-07-20 04:54:45 +08:00
Mike-Solar 37845302f9 engine: begin the liboakengine C ABI facade with the IPC subsystem
- oakengine/export.h establishes the OAKENGINE_API visibility macros;
  include/oakengine/ipc.h is the first pure-C surface (41 functions:
  shm, frame slot pool, and the worker IPC messages as POD<->JSON
  build/parse), implemented in engine/src/capi/
- the IPC implementations move to engine/src/oliveimpl (namespace
  olive::engine::internal::ipc); engine/render/ipc/*.h are rebuilt as
  same-name/same-API wrapper classes forwarding across the C boundary
- FrameSlotMeta is shared with the C header verbatim so the app/worker
  wire format (v1) is bit-identical; static_asserts pin sizeof and
  field offsets
- spscringbuffer.h moves to include/oakengine/ as an inline-only
  header (no symbols, not ABI)
- new pure-C test oakengine_ipc_test (make_oakengine_test, no GL)
  covers shm, frame pool, message round-trips and the layout asserts;
  full gtest suite stays green (1986 tests)
2026-07-20 04:12:58 +08:00
Mike-Solar 28c4426236 build: split the engine into liboakengine.so; worker drops the UI entirely
Physical split: app/{audio,cli,codec,common,config,node,pluginSupport,
render,task,timeline,undo,tool,shaders} plus coreengine, version and
ui/icons+colorcoding move to a new top-level engine/ tree, built as
liboakengine.so (shared). The render backends (oakgl/oakvulkan) move
with it and link the engine library instead of embedding a static
render-core subset (libolive-rendercore is gone).

- oak-render-worker now links liboakengine instead of the whole
  libolive-editor object set: 336MB -> 2.9MB, no Qt Widgets UI
- the editor links liboakengine for the engine and keeps only UI
  objects in libolive-editor
- install/packaging: GNUInstallDirs libdir on Linux, bundle copy on
  macOS, oakengine.dll staged for NSIS, AppImage validation entry
- fix backend lookup for the new layout: DynamicRenderer searched
  ../app but backends now live in engine/; a stale pre-split liboakgl
  in the build tree got dlopened instead, re-initialized and later
  destroyed the interposed engine statics (full-suite segfault at
  DialogSequenceParameterTab, found via gdb watchpoint)
2026-07-20 03:23:28 +08:00