@@ -9,6 +9,9 @@ class OtherDisplay: Display {
99 var arm64ddc : Bool = false
1010 var arm64avService : IOAVService ?
1111 var isDiscouraged : Bool = false
12+ let writeDDCQueue = DispatchQueue ( label : " Local write DDC queue " )
13+ var writeDDCNextValue : [ Command : UInt16 ] = [ : ]
14+ var writeDDCLastSavedValue : [ Command : UInt16 ] = [ : ]
1215 var pollingCount : Int {
1316 get {
1417 switch self . readPrefAsInt ( key : . pollingMode ) {
@@ -76,11 +79,11 @@ class OtherDisplay: Display {
7679 if ! self . smoothBrightnessRunning , ! self . isSw ( ) , ! self . readPrefAsBool ( key : . unavailableDDC , for : command ) , self . readPrefAsBool ( key : . isTouched , for : command ) , prefs . integer ( forKey : PrefKey . startupAction . rawValue ) == StartupAction . write . rawValue , ! app . safeMode {
7780 let restoreValue = self . getDDCValueFromPrefs ( command )
7881 os_log ( " Restoring %{public}@ DDC value %{public}@ for %{public}@ " , type : . info , String ( reflecting : command ) , String ( restoreValue ) , self . name )
79- _ = self . writeDDCValues ( command : command , value : restoreValue )
82+ self . writeDDCValues ( command : command , value : restoreValue )
8083 if command == . audioSpeakerVolume , self . readPrefAsBool ( key : . enableMuteUnmute ) {
8184 let currentMuteValue = self . readPrefAsInt ( for : . audioMuteScreenBlank ) == 0 ? 2 : self . readPrefAsInt ( for : . audioMuteScreenBlank )
8285 os_log ( " - Writing last saved DDC value for Mute: %{public}@ " , type : . info , String ( currentMuteValue ) )
83- _ = self . writeDDCValues ( command : . audioMuteScreenBlank , value : UInt16 ( currentMuteValue ) )
86+ self . writeDDCValues ( command : . audioMuteScreenBlank , value : UInt16 ( currentMuteValue ) )
8487 }
8588 }
8689 }
@@ -178,13 +181,11 @@ class OtherDisplay: Display {
178181 let isAlreadySet = volumeOSDValue == self . readPrefAsFloat ( for : . audioSpeakerVolume )
179182 if ! isAlreadySet {
180183 if let muteValue = muteValue , self . readPrefAsBool ( key : . enableMuteUnmute ) {
181- guard self . writeDDCValues ( command : . audioMuteScreenBlank , value : UInt16 ( muteValue ) ) == true else {
182- return
183- }
184+ self . writeDDCValues ( command : . audioMuteScreenBlank , value : UInt16 ( muteValue ) )
184185 self . savePref ( muteValue , for : . audioMuteScreenBlank )
185186 }
186187 if ! self . readPrefAsBool ( key : . enableMuteUnmute ) || volumeOSDValue != 0 {
187- _ = self . writeDDCValues ( command : . audioSpeakerVolume , value : self . convValueToDDC ( for : . audioSpeakerVolume , from : volumeOSDValue ) )
188+ self . writeDDCValues ( command : . audioSpeakerVolume , value : self . convValueToDDC ( for : . audioSpeakerVolume , from : volumeOSDValue ) )
188189 }
189190 }
190191 if ! self . readPrefAsBool ( key : . hideOsd ) {
@@ -206,7 +207,7 @@ class OtherDisplay: Display {
206207 let contrastOSDValue = self . calcNewValue ( currentValue : currentValue , isUp : isUp , isSmallIncrement : isSmallIncrement )
207208 let isAlreadySet = contrastOSDValue == self . readPrefAsFloat ( for : . contrast )
208209 if ! isAlreadySet {
209- _ = self . writeDDCValues ( command : . contrast , value : self . convValueToDDC ( for : . contrast , from : contrastOSDValue ) )
210+ self . writeDDCValues ( command : . contrast , value : self . convValueToDDC ( for : . contrast , from : contrastOSDValue ) )
210211 }
211212 OSDUtils . showOsd ( displayID : self . identifier , command : . contrast , value : contrastOSDValue , roundChiclet : ! isSmallIncrement )
212213 if ! isAlreadySet {
@@ -237,13 +238,11 @@ class OtherDisplay: Display {
237238 }
238239 }
239240 if self . readPrefAsBool ( key : . enableMuteUnmute ) {
240- guard self . writeDDCValues ( command : . audioMuteScreenBlank , value : UInt16 ( muteValue ) ) == true else {
241- return
242- }
241+ self . writeDDCValues ( command : . audioMuteScreenBlank , value : UInt16 ( muteValue ) )
243242 }
244243 self . savePref ( muteValue , for : . audioMuteScreenBlank )
245244 if ! self . readPrefAsBool ( key : . enableMuteUnmute ) || volumeOSDValue > 0 {
246- _ = self . writeDDCValues ( command : . audioSpeakerVolume , value : self . convValueToDDC ( for : . audioSpeakerVolume , from : volumeOSDValue ) )
245+ self . writeDDCValues ( command : . audioSpeakerVolume , value : self . convValueToDDC ( for : . audioSpeakerVolume , from : volumeOSDValue ) )
247246 }
248247 if ! fromVolumeSlider {
249248 if ! self . readPrefAsBool ( key : . hideOsd ) {
@@ -345,12 +344,12 @@ class OtherDisplay: Display {
345344 brightnessValue = 0
346345 brightnessSwValue = ( value / self . combinedBrightnessSwitchingValue ( ) )
347346 }
348- _ = self . writeDDCValues ( command : . brightness , value : self . convValueToDDC ( for : . brightness , from : brightnessValue ) )
347+ self . writeDDCValues ( command : . brightness , value : self . convValueToDDC ( for : . brightness , from : brightnessValue ) )
349348 if self . readPrefAsFloat ( key : . SwBrightness ) != brightnessSwValue {
350349 _ = self . setSwBrightness ( brightnessSwValue )
351350 }
352351 } else {
353- _ = self . writeDDCValues ( command : . brightness , value : self . convValueToDDC ( for : . brightness , from : value ) )
352+ self . writeDDCValues ( command : . brightness , value : self . convValueToDDC ( for : . brightness , from : value ) )
354353 }
355354 if ! transient {
356355 self . savePref ( value , for : . brightness )
@@ -378,28 +377,45 @@ class OtherDisplay: Display {
378377 return intCodes
379378 }
380379
381- public func writeDDCValues ( command : Command , value : UInt16 , errorRecoveryWaitTime _ : UInt32 ? = nil ) -> Bool ? {
380+ public func writeDDCValues ( command : Command , value : UInt16 ) {
382381 guard app . sleepID == 0 , app . reconfigureID == 0 , ! self . readPrefAsBool ( key : . forceSw ) , ! self . readPrefAsBool ( key : . unavailableDDC , for : command ) else {
383- return false
382+ return
383+ }
384+ self . writeDDCQueue . async ( flags : . barrier ) {
385+ self . writeDDCNextValue [ command ] = value
386+ }
387+ DisplayManager . shared . globalDDCQueue . async ( flags : . barrier ) {
388+ self . asyncPerformWriteDDCValues ( command : command )
389+ }
390+ }
391+
392+ func asyncPerformWriteDDCValues ( command : Command ) {
393+ var value = UInt16 . max
394+ var lastValue = UInt16 . max
395+ self . writeDDCQueue . sync {
396+ value = self . writeDDCNextValue [ command ] ?? UInt16 . max
397+ lastValue = self . writeDDCLastSavedValue [ command ] ?? UInt16 . max
398+ }
399+ guard value != UInt16 . max , value != lastValue else {
400+ return
401+ }
402+ self . writeDDCQueue . async ( flags : . barrier ) {
403+ self . writeDDCLastSavedValue [ command ] = value
404+ self . savePref ( true , key : PrefKey . isTouched , for : command )
384405 }
385- var success : Bool = false
386406 var controlCodes = self . getRemapControlCodes ( command : command )
387407 if controlCodes . count == 0 {
388408 controlCodes . append ( command . rawValue )
389409 }
390410 for controlCode in controlCodes {
391- DisplayManager . shared . ddcQueue . sync {
392- if Arm64DDC . isArm64 {
393- if self . arm64ddc {
394- success = Arm64DDC . write ( service : self . arm64avService , command : controlCode , value : value )
395- }
396- } else {
397- success = self . ddc ? . write ( command : command . rawValue , value : value , errorRecoveryWaitTime : 2000 ) ?? false
411+ if Arm64DDC . isArm64 {
412+ if self . arm64ddc {
413+ _ = Arm64DDC . write ( service : self . arm64avService , command : controlCode , value : value )
398414 }
399- self . savePref ( true , key : PrefKey . isTouched , for : command ) // We deliberatly consider the value tuched no matter if the call succeeded
415+ } else {
416+ _ = self . ddc ? . write ( command : controlCode , value : value , errorRecoveryWaitTime : 2000 ) ?? false
400417 }
401418 }
402- return success
403419 }
404420
405421 func readDDCValues ( for command : Command , tries : UInt , minReplyDelay delay : UInt64 ? ) -> ( current : UInt16 , max : UInt16 ) ? {
@@ -413,15 +429,15 @@ class OtherDisplay: Display {
413429 guard self . arm64ddc else {
414430 return nil
415431 }
416- DisplayManager . shared . ddcQueue . sync {
432+ DisplayManager . shared . globalDDCQueue . sync {
417433 if let unwrappedDelay = delay {
418434 values = Arm64DDC . read ( service : self . arm64avService , command : controlCode , tries : UInt8 ( min ( tries , 255 ) ) , minReplyDelay : UInt32 ( unwrappedDelay / 1000 ) )
419435 } else {
420436 values = Arm64DDC . read ( service : self . arm64avService , command : controlCode , tries : UInt8 ( min ( tries , 255 ) ) )
421437 }
422438 }
423439 } else {
424- DisplayManager . shared . ddcQueue . sync {
440+ DisplayManager . shared . globalDDCQueue . sync {
425441 values = self . ddc ? . read ( command : controlCode , tries : tries , minReplyDelay : delay )
426442 }
427443 }
0 commit comments