Skip to content

Commit

Permalink
优化代码架构
Browse files Browse the repository at this point in the history
  • Loading branch information
shadow3aaa committed Dec 30, 2023
1 parent 95c5acf commit 576f9c8
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 105 deletions.
101 changes: 61 additions & 40 deletions fas-rs-fw/src/scheduler/looper/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
* limitations under the License. */
mod buffer;
mod policy;
mod policy_config;
mod utils;
mod window;

Expand All @@ -23,17 +22,16 @@ use std::{
time::Duration,
};

use super::{topapp::TimedWatcher, BinderMessage};
use super::{topapp::TimedWatcher, BinderMessage, FasData};
use crate::{
config::Config,
error::{Error, Result},
node::Node,
node::{Mode, Node},
PerformanceController,
};

use buffer::Buffer;
use policy::Event;
use policy_config::PolicyConfig;

pub type Producer = (i64, i32); // buffer, pid
pub type Buffers = HashMap<Producer, Buffer>; // Process, (jank_scale, total_jank_time_ns)
Expand Down Expand Up @@ -70,23 +68,9 @@ impl<P: PerformanceController> Looper<P> {
.filter(|b| b.last_update.elapsed() < Duration::from_secs(1))
.filter_map(|b| b.target_fps)
.max();
let timeout = Duration::from_secs(10) / target_fps.unwrap_or(10);

let message = match self.rx.recv_timeout(timeout) {
Ok(m) => m,
Err(e) => {
if e == RecvTimeoutError::Disconnected {
return Err(Error::Other("Binder Server Disconnected"));
}

self.retain_topapp(mode)?;

if self.started {
self.controller.release_max(mode, &self.config)?;
}

continue;
}
let Some(message) = self.recv_message(mode, target_fps)? else {
continue;
};

let data = match message {
Expand All @@ -97,34 +81,71 @@ impl<P: PerformanceController> Looper<P> {
}
};

self.buffer_update(&data);
self.retain_topapp(mode)?;
self.consume_data(mode, data)?;

if !self.started {
continue;
}

let mut event = Event::None;
for buffer in self
.buffers
.values_mut()
.filter(|b| b.last_update.elapsed() < Duration::from_secs(1))
.filter(|b| target_fps.is_none() || b.target_fps == target_fps)
{
let policy_config = PolicyConfig::new(mode, buffer);
let current_event = Self::get_event(buffer, policy_config);
event = event.max(current_event);
}
self.do_policy(mode, target_fps)?;
}
}

match event {
Event::ReleaseMax => {
self.controller.release_max(mode, &self.config)?;
fn recv_message(
&mut self,
mode: Mode,
target_fps: Option<u32>,
) -> Result<Option<BinderMessage>> {
let timeout = target_fps
.and_then(|t| Some(Duration::from_secs(10) / t))
.unwrap_or(Duration::from_secs(1));

match self.rx.recv_timeout(timeout) {
Ok(m) => Ok(Some(m)),
Err(e) => {
if e == RecvTimeoutError::Disconnected {
return Err(Error::Other("Binder Server Disconnected"));
}
Event::Release => {
self.controller.release(mode, &self.config)?;

self.retain_topapp(mode)?;

if self.started {
self.controller.release_max(mode, &self.config)?;
}
Event::Limit => self.controller.limit(mode, &self.config)?,
Event::None => (),

Ok(None)
}
}
}

fn consume_data(&mut self, mode: Mode, data: FasData) -> Result<()> {
self.buffer_update(&data);
self.retain_topapp(mode)
}

fn do_policy(&mut self, mode: Mode, target_fps: Option<u32>) -> Result<()> {
let mut event = Event::None;
for buffer in self
.buffers
.values_mut()
.filter(|b| b.last_update.elapsed() < Duration::from_secs(1))
.filter(|b| target_fps.is_none() || b.target_fps == target_fps)
{
let current_event = Self::get_event(mode, buffer);
event = event.max(current_event);
}

match event {
Event::ReleaseMax => {
self.controller.release_max(mode, &self.config)?;
}
Event::Release => {
self.controller.release(mode, &self.config)?;
}
Event::Limit => self.controller.limit(mode, &self.config)?,
Event::None => (),
}

Ok(())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* limitations under the License. */
use std::time::Duration;

use super::Buffer;
use super::super::Buffer;
use crate::node::Mode;

#[derive(Debug, Clone, Copy)]
Expand Down
46 changes: 46 additions & 0 deletions fas-rs-fw/src/scheduler/looper/policy/extract.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/* Copyright 2023 [email protected]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. */
use std::time::Duration;

use super::super::buffer::Buffer;

#[derive(Debug, Clone, Copy)]
pub struct PolicyData {
pub target_fps: u32,
pub normalized_big_jank_scale: Duration,
pub normalized_jank_scale: Duration,
pub normalized_frame: Duration,
pub normalized_avg_frame: Duration,
}

impl PolicyData {
pub fn extract(buffer: &Buffer) -> Option<Self> {
let target_fps = buffer.target_fps?;
let window = buffer.windows.get(&target_fps)?;
let normalized_avg_frame = window.avg_normalized(f64::from(target_fps))?;
let last_frame = window.last()?;
let normalized_frame = last_frame * target_fps;

let normalized_big_jank_scale = Duration::from_secs(5);
let normalized_jank_scale = Duration::from_millis(1700);

Some(Self {
target_fps,
normalized_big_jank_scale,
normalized_jank_scale,
normalized_frame,
normalized_avg_frame,
})
}
}
110 changes: 48 additions & 62 deletions fas-rs-fw/src/scheduler/looper/policy.rs → fas-rs-fw/src/scheduler/looper/policy/mod.rs
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License. */
pub mod config;
mod extract;

use std::time::{Duration, Instant};

#[cfg(debug_assertions)]
use log::debug;

use super::{Buffer, Looper, PolicyConfig};
use crate::PerformanceController;
use super::{Buffer, Looper};
use crate::{Mode, PerformanceController};

use config::PolicyConfig;
use extract::PolicyData;

#[derive(Debug, PartialEq, Eq, Ord, PartialOrd, Copy, Clone)]
pub enum Event {
Expand All @@ -28,75 +34,31 @@ pub enum Event {
}

impl<P: PerformanceController> Looper<P> {
pub fn get_event(buffer: &mut Buffer, config: PolicyConfig) -> Event {
#[cfg(debug_assertions)]
debug!("policy config: {config:?}");

let Some(target_fps) = buffer.target_fps else {
#[cfg(debug_assertions)]
debug!("Failed to do policy: Missing target_fps");

return Event::None;
};

let Some(window) = buffer.windows.get_mut(&target_fps) else {
#[cfg(debug_assertions)]
debug!("Failed to do policy: Missing target frame window");

pub fn get_event(mode: Mode, buffer: &mut Buffer) -> Event {
let config = PolicyConfig::new(mode, buffer);
let Some(policy_data) = PolicyData::extract(buffer) else {
return Event::None;
};

let Some(normalized_avg_frame) = window.avg_normalized(f64::from(target_fps)) else {
#[cfg(debug_assertions)]
debug!("Failed to do policy: Missing avg_frame");

return Event::None;
};

let Some(last_frame) = window.last().copied() else {
#[cfg(debug_assertions)]
debug!("Failed to do policy: Missing last_frame");

return Event::None;
};
let normalized_frame = last_frame * target_fps;

let normalized_big_jank_scale = Duration::from_secs(5);
let normalized_jank_scale = Duration::from_millis(1700);

#[cfg(debug_assertions)]
{
debug!("target_fps: {target_fps}");
debug!("normalized frametime: {normalized_frame:?}");
debug!("normalized avg frametime: {normalized_avg_frame:?}");
debug!("simple jank scale: {normalized_jank_scale:?}");
debug!("big jank scale: {normalized_big_jank_scale:?}");
debug!("policy config: {config:?}");
debug!("policy data: {policy_data:?}");
}

if normalized_frame > normalized_big_jank_scale {
#[cfg(debug_assertions)]
debug!("JANK: big jank");

return Event::ReleaseMax;
} else if normalized_frame > normalized_jank_scale {
if let Some(stamp) = buffer.last_jank {
if stamp.elapsed() * target_fps < Duration::from_secs(30) {
return Event::None;
}
}

buffer.last_jank = Some(Instant::now());

#[cfg(debug_assertions)]
debug!("JANK: simp jank");

return Event::Release;

let result = Self::frame_analyze(buffer, config, policy_data);
if let Some(event) = Self::jank_analyze(buffer, policy_data) {
return event;
}

let diff = normalized_avg_frame.as_secs_f64() - 1.0;
result
}

fn frame_analyze(buffer: &mut Buffer, config: PolicyConfig, policy_data: PolicyData) -> Event {
let diff = policy_data.normalized_avg_frame.as_secs_f64() - 1.0;
buffer.acc_frame += diff;

if buffer.acc_timer.elapsed() * target_fps < config.acc_dur {
if buffer.acc_timer.elapsed() * policy_data.target_fps < config.acc_dur {
return Event::None;
}

Expand All @@ -111,7 +73,7 @@ impl<P: PerformanceController> Looper<P> {
debug!("JANK: no jank");

if let Some(stamp) = buffer.last_limit {
if stamp.elapsed() * target_fps < Duration::from_secs(3) {
if stamp.elapsed() * policy_data.target_fps < Duration::from_secs(3) {
Event::None
} else {
buffer.last_limit = Some(Instant::now());
Expand All @@ -130,4 +92,28 @@ impl<P: PerformanceController> Looper<P> {

result
}

fn jank_analyze(buffer: &mut Buffer, policy_data: PolicyData) -> Option<Event> {
if policy_data.normalized_frame > policy_data.normalized_big_jank_scale {
#[cfg(debug_assertions)]
debug!("JANK: big jank");

Some(Event::ReleaseMax)
} else if policy_data.normalized_frame > policy_data.normalized_jank_scale {
if let Some(stamp) = buffer.last_jank {
if stamp.elapsed() * policy_data.target_fps < Duration::from_secs(30) {
return Some(Event::None);
}
}

buffer.last_jank = Some(Instant::now());

#[cfg(debug_assertions)]
debug!("JANK: simp jank");

Some(Event::Release)
} else {
None
}
}
}
4 changes: 2 additions & 2 deletions fas-rs-fw/src/scheduler/looper/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ impl FrameWindow {
self.frametimes.truncate(self.len);
}

pub fn last(&mut self) -> Option<&mut Duration> {
pub fn last(&self) -> Option<Duration> {
if self.frametimes.len() < self.len {
None
} else {
self.frametimes.front_mut()
self.frametimes.front().copied()
}
}

Expand Down

0 comments on commit 576f9c8

Please sign in to comment.