Ω-W1-T3: run the master meter on its own 60 FPS timer, and make a meter frame cost one rect
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
@@ -118,7 +119,13 @@ private:
|
||||
FaceLayout faceLayout(int w, int h) const;
|
||||
|
||||
#ifdef _WIN32
|
||||
void paint(HDC hdc);
|
||||
// `dirty` is the host's WM_PAINT update rect: a region inside the meter's bar field redraws
|
||||
// that field alone, anything else re-composes the face, and either way only the dirty region
|
||||
// is blitted out of the retained back buffer (a per-paint client-area LICE_SysBitmap is what
|
||||
// the meter's rate would otherwise cost).
|
||||
void paint(HDC hdc, const RECT& dirty);
|
||||
LICE_IBitmap* ensureBackBuffer(int w, int h);
|
||||
void releaseBackBuffer();
|
||||
void paintSample(LICE_IBitmap* bmp, int w, int h); // home face (band composition)
|
||||
void paintBrowse(LICE_IBitmap* bmp, int w, int h); // modal picker overlay
|
||||
void paintEmptyState(LICE_IBitmap* bmp, const Rect& area);
|
||||
@@ -137,6 +144,7 @@ private:
|
||||
// Decks: the group fence + caption + compact caption toggles + radial knobs with
|
||||
// label<->value swap on hover/drag.
|
||||
void paintDeck(LICE_IBitmap* bmp, const FaceLayout& fl);
|
||||
void paintMeterField(LICE_IBitmap* bmp); // the bar field alone, off meterRects_
|
||||
|
||||
// A deck cell's mini curve thumbnail (the VELOCITY group) and the modal editor it summons.
|
||||
void paintCurveButton(LICE_IBitmap* bmp, const Rect& r, CurveTarget target, bool disabled,
|
||||
@@ -231,10 +239,16 @@ private:
|
||||
// never yanks the edit surface.
|
||||
void onSyncTimer();
|
||||
|
||||
// The meter tick (its own WM_TIMER id, UI thread only): drains the bus, advances the
|
||||
// ballistics, repaints the bar field. Its own clock — see editor_platform.cpp's timer ids.
|
||||
void onMeterTimer();
|
||||
|
||||
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void invalidate();
|
||||
void invalidateMeter(); // the bar field only; falls back to invalidate() before first paint
|
||||
|
||||
HWND childHwnd_ = nullptr;
|
||||
LICE_IBitmap* backBuffer_ = nullptr; // owned; see ensureBackBuffer
|
||||
#endif
|
||||
|
||||
// Re-read the bank (samples + banks) from the live bridge and snapshot the instrument's
|
||||
@@ -280,10 +294,16 @@ private:
|
||||
// thread only (file I/O); cleared with the thumbnail cache on refresh.
|
||||
const std::vector<AudioSample>& monoPcmFor(const std::string& sampleId);
|
||||
|
||||
// The hero waveform's binned envelope: the band's most expensive draw, and a function of the
|
||||
// capture and the bin count alone. UI thread only (may decode).
|
||||
const Envelope& heroEnvelope(std::size_t bins, int laneCount);
|
||||
|
||||
// The interleaved source PCM behind the stereo waveform lanes.
|
||||
struct ChannelPcm {
|
||||
std::vector<AudioSample> interleaved; // frame-interleaved source frames
|
||||
int channelCount = 0; // 0 = nothing decoded
|
||||
Envelope heroEnv; // binned from `interleaved`, so every path that drops the
|
||||
std::size_t heroBins = 0; // decode drops it too. 0 = not computed
|
||||
std::int64_t frameCount() const {
|
||||
return channelCount > 0
|
||||
? static_cast<std::int64_t>(interleaved.size()) / channelCount
|
||||
@@ -471,11 +491,14 @@ private:
|
||||
std::string searchQuery_; // type-to-filter narrow; "" = no search
|
||||
bool searchFocused_ = false; // whether the search box has keyboard focus
|
||||
|
||||
// The MASTER deck's meter, advanced from the published block magnitudes on the sync tick
|
||||
// (see onSyncTimer for why it runs mid-drag too, and why the first read is discarded).
|
||||
// meterTickMs_ 0 = never ticked.
|
||||
// The MASTER deck's meter, advanced from the published block magnitudes on its own timer
|
||||
// (see onMeterTimer for why it runs mid-drag too, and why the first read is discarded).
|
||||
// A default-constructed meterTick_ means never ticked. meterRects_ is the column interior
|
||||
// resolved at the last FULL paint; an empty field means "not on screen" (no layout yet, the
|
||||
// empty state, a modal sheet over it) and sends the tick down the whole-client path.
|
||||
instrument::ui::MasterMeterUi masterMeter_;
|
||||
unsigned long long meterTickMs_ = 0;
|
||||
std::chrono::steady_clock::time_point meterTick_{};
|
||||
instrument::ui::MeterRects meterRects_;
|
||||
|
||||
// Hover state (transient, never persisted).
|
||||
HoverTarget hover_; // the interactive element under the pointer
|
||||
|
||||
Reference in New Issue
Block a user