Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
index f8583e9ac73c8aced220bd12a25a357bf0426f3e..fd3c63be07dbb70bd8024570d71101c76059182c 100644 |
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc |
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc |
@@ -8,6 +8,7 @@ |
#include <algorithm> |
#include <cmath> |
+#include <iostream> |
#include <list> |
#include <map> |
#include <queue> |
@@ -76,6 +77,8 @@ |
#include <OpenGL/CGLIOSurface.h> |
#endif |
+#include "content/renderer/greenweb_latency_tracking.h" |
+ |
namespace gpu { |
namespace gles2 { |
@@ -11927,7 +11930,93 @@ error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size, |
#endif |
} |
+void set_freq(uint32 freq) |
+{ |
+ FILE *cpufreq = NULL; |
+ |
+ if(!cpufreq) |
+ { |
+ cpufreq = fopen("/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed", "w"); |
+ if(!cpufreq) |
+ dbg_sched_fprintf(stdout, "[EBS] file open failed\n"); |
+ } |
+ |
+ if(cpufreq) |
+ { |
+ int bytes = fprintf(cpufreq, "%u", freq); |
+ if((bytes != 6) && (bytes != 7)) |
+ dbg_sched_fprintf(stdout, "[EBS] cpufreq not set\n"); |
+ fclose(cpufreq); |
+ } |
+} |
+ |
+uint32 schedule(int64 latency, uint32 freq, int64 target) { |
+ uint32 next_freq; |
+ float target_f, latency_f; |
+ target_f = (float)target; |
+ latency_f = (float)latency; |
+ |
+ if (latency_f > target_f * 0.9) { |
+ // Under predicting |
+ if (latency_f > target_f * 2) |
+ next_freq = 16; |
+ else { |
+ if(freq == 16) next_freq = 16; |
+ else if(freq == 6) next_freq = 8; |
+ else next_freq = freq + 1; |
+ } |
+ } |
+ else if (latency_f < target_f * 0.8) { |
+ // Over predicting |
+ if (target_f > latency_f * 2) |
+ next_freq = 4; |
+ else { |
+ if(freq == 4) next_freq = 4; |
+ else if(freq == 8) next_freq = 6; |
+ else next_freq = freq - 1; |
+ } |
+ } |
+ else { |
+ // Keep last prediction |
+ next_freq = freq; |
+ } |
+ |
+#ifdef EBS_DEBUG_TRACE_EVENT |
+ TRACE_EVENT2("gpu", "SetFrequency", |
+ "previous frame latency", latency, |
+ "freq", next_freq); |
+#endif |
+ |
+ return next_freq; |
+} |
+ |
void GLES2DecoderImpl::DoSwapBuffers() { |
+ static base::TimeTicks frame_ts; |
+ base::TimeTicks ts = base::TimeTicks::Now(); |
+ base::TimeDelta frame_latency = ts - frame_ts; |
+ int64 frame_latency_in_ms = frame_latency.InMilliseconds(); |
+ frame_ts = ts; |
+ |
+ dbg_ipc_cout("GPU: g_ebs_enabled " << g_ebs_enabled << |
+ ", g_qos_type " << g_qos_type << |
+ ", g_qos_target" << g_qos_target); |
+ if (g_ebs_enabled && (g_qos_type == 'c')) { |
+ static uint32 last_freq; |
+ |
+ uint32 next_freq = schedule(frame_latency_in_ms, |
+ last_freq, |
+ g_qos_target); |
+ set_freq(next_freq * 100000); |
+ last_freq = next_freq; |
+ dbg_sched_fprintf(stdout, "[EBS] set freq to %u last_latency %lld\n", next_freq, frame_latency_in_ms); |
+ } |
+#ifdef EBS_DEBUG_OS |
+ else { |
+ fprintf(stdout, "[OS] last_latency %lld\n", frame_latency_in_ms); |
+ } |
+#endif |
+ fflush(stdout); |
+ |
bool is_offscreen = !!offscreen_target_frame_buffer_.get(); |
int this_frame_number = frame_number_++; |