1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-24 12:30:17 +00:00

Reduce modal-related thread hopping.

This commit is contained in:
Thomas Harte 2022-07-09 13:03:45 -04:00
parent b097b1296b
commit 51ed3f2ed0
3 changed files with 23 additions and 10 deletions

View File

@ -939,12 +939,14 @@ using BufferingScanTarget = Outputs::Display::BufferingScanTarget;
- (void)updateFrameBuffer {
// TODO: rethink BufferingScanTarget::perform. Is it now really just for guarding the modals?
if(_scanTarget.has_new_modals()) {
_scanTarget.perform([=] {
const Outputs::Display::ScanTarget::Modals *const newModals = _scanTarget.new_modals();
if(newModals) {
[self setModals:*newModals];
}
});
}
@synchronized(self) {
if(!_frameBufferRenderPass) return;

View File

@ -302,7 +302,7 @@ size_t BufferingScanTarget::write_area_data_size() const {
void BufferingScanTarget::set_modals(Modals modals) {
perform([=] {
modals_ = modals;
modals_are_dirty_ = true;
modals_are_dirty_.store(true, std::memory_order::memory_order_relaxed);
});
}
@ -374,10 +374,12 @@ void BufferingScanTarget::set_line_buffer(Line *line_buffer, LineMetadata *metad
}
const Outputs::Display::ScanTarget::Modals *BufferingScanTarget::new_modals() {
if(!modals_are_dirty_) {
const auto modals_are_dirty = modals_are_dirty_.load(std::memory_order::memory_order_relaxed);
if(!modals_are_dirty) {
return nullptr;
}
modals_are_dirty_ = false;
modals_are_dirty_.store(false, std::memory_order::memory_order_relaxed);
// MAJOR SHARP EDGE HERE: assume that because the new_modals have been fetched then the caller will
// now ensure their texture buffer is appropriate. They might provide a new pointer and might now.
@ -392,3 +394,7 @@ const Outputs::Display::ScanTarget::Modals *BufferingScanTarget::new_modals() {
const Outputs::Display::ScanTarget::Modals &BufferingScanTarget::modals() const {
return modals_;
}
bool BufferingScanTarget::has_new_modals() const {
return modals_are_dirty_.load(std::memory_order::memory_order_relaxed);
}

View File

@ -161,6 +161,11 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget {
/// @returns the current @c Modals.
const Modals &modals() const;
/// @returns @c true if new modals are available; @c false otherwise.
///
/// Safe to call from any thread.
bool has_new_modals() const;
private:
// ScanTarget overrides.
void set_modals(Modals) final;
@ -253,7 +258,7 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget {
// Current modals and whether they've yet been returned
// from a call to @c get_new_modals.
Modals modals_;
bool modals_are_dirty_ = false;
std::atomic<bool> modals_are_dirty_ = false;
// Provides a per-data size implementation of end_data; a previous
// implementation used blind memcpy and that turned into something