/*
* Copyright (C) 2015-2016 Willi Ye <williye97@gmail.com>
*
* This file is part of Kernel Adiutor.
*
* Kernel Adiutor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Kernel Adiutor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Kernel Adiutor. If not, see <http://www.gnu.org/licenses/>.
*
*/
package com.grarak.kerneladiutor.fragments.kernel;
import com.grarak.kerneladiutor.R;
import com.grarak.kerneladiutor.fragments.ApplyOnBootFragment;
import com.grarak.kerneladiutor.fragments.BaseFragment;
import com.grarak.kerneladiutor.fragments.RecyclerViewFragment;
import com.grarak.kerneladiutor.utils.kernel.gpu.AdrenoIdler;
import com.grarak.kerneladiutor.utils.kernel.gpu.GPUFreq;
import com.grarak.kerneladiutor.utils.kernel.gpu.SimpleGPU;
import com.grarak.kerneladiutor.views.recyclerview.CardView;
import com.grarak.kerneladiutor.views.recyclerview.DescriptionView;
import com.grarak.kerneladiutor.views.recyclerview.RecyclerViewItem;
import com.grarak.kerneladiutor.views.recyclerview.SeekBarView;
import com.grarak.kerneladiutor.views.recyclerview.SelectView;
import com.grarak.kerneladiutor.views.recyclerview.SwitchView;
import com.grarak.kerneladiutor.views.recyclerview.TitleView;
import com.grarak.kerneladiutor.views.recyclerview.XYGraphView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by willi on 12.05.16.
*/
public class GPUFragment extends RecyclerViewFragment {
private XYGraphView m2dCurFreq;
private XYGraphView mCurFreq;
private PathReaderFragment mGPUGovernorTunableFragment;
@Override
protected BaseFragment getForegroundFragment() {
return mGPUGovernorTunableFragment = new PathReaderFragment();
}
@Override
protected void init() {
super.init();
addViewPagerFragment(ApplyOnBootFragment.newInstance(this));
}
@Override
protected void addItems(List<RecyclerViewItem> items) {
freqInit(items);
governorInit(items);
if (SimpleGPU.supported()) {
simpleGpuInit(items);
}
if (AdrenoIdler.supported()) {
adrenoIdlerInit(items);
}
}
private void freqInit(List<RecyclerViewItem> items) {
CardView freqCard = new CardView(getActivity());
freqCard.setTitle(getString(R.string.frequencies));
if (GPUFreq.has2dCurFreq() && GPUFreq.get2dAvailableFreqs() != null) {
m2dCurFreq = new XYGraphView();
m2dCurFreq.setTitle(getString(R.string.gpu_2d_freq));
freqCard.addItem(m2dCurFreq);
}
if (GPUFreq.hasCurFreq() && GPUFreq.getAvailableFreqs() != null) {
mCurFreq = new XYGraphView();
mCurFreq.setTitle(getString(R.string.gpu_freq));
freqCard.addItem(mCurFreq);
}
if (GPUFreq.has2dMaxFreq() && GPUFreq.get2dAvailableFreqs() != null) {
SelectView max2dFreq = new SelectView();
max2dFreq.setTitle(getString(R.string.gpu_2d_max_freq));
max2dFreq.setSummary(getString(R.string.gpu_2d_max_freq_summary));
max2dFreq.setItems(GPUFreq.get2dAdjustedFreqs(getActivity()));
max2dFreq.setItem((GPUFreq.get2dMaxFreq() / 1000000) + getString(R.string.mhz));
max2dFreq.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
GPUFreq.set2dMaxFreq(GPUFreq.get2dAvailableFreqs().get(position), getActivity());
}
});
freqCard.addItem(max2dFreq);
}
if (GPUFreq.hasMaxFreq() && GPUFreq.getAvailableFreqs() != null) {
SelectView maxFreq = new SelectView();
maxFreq.setTitle(getString(R.string.gpu_max_freq));
maxFreq.setSummary(getString(R.string.gpu_max_freq_summary));
maxFreq.setItems(GPUFreq.getAdjustedFreqs(getActivity()));
maxFreq.setItem((GPUFreq.getMaxFreq() / GPUFreq.getMaxFreqOffset()) + getString(R.string.mhz));
maxFreq.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
GPUFreq.setMaxFreq(GPUFreq.getAvailableFreqs().get(position), getActivity());
}
});
freqCard.addItem(maxFreq);
}
if (GPUFreq.hasMinFreq() && GPUFreq.getAvailableFreqs() != null) {
SelectView minFreq = new SelectView();
minFreq.setTitle(getString(R.string.gpu_min_freq));
minFreq.setSummary(getString(R.string.gpu_min_freq_summary));
minFreq.setItems(GPUFreq.getAdjustedFreqs(getActivity()));
minFreq.setItem((GPUFreq.getMinFreq() / GPUFreq.getMinFreqOffset()) + getString(R.string.mhz));
minFreq.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
GPUFreq.setMinFreq(GPUFreq.getAvailableFreqs().get(position), getActivity());
}
});
freqCard.addItem(minFreq);
}
if (freqCard.size() > 0) {
items.add(freqCard);
}
}
private void governorInit(List<RecyclerViewItem> items) {
if (GPUFreq.has2dGovernor()) {
SelectView governor2d = new SelectView();
governor2d.setTitle(getString(R.string.gpu_2d_governor));
governor2d.setSummary(getString(R.string.gpu_2d_governor_summary));
governor2d.setItems(GPUFreq.get2dAvailableGovernors());
governor2d.setItem(GPUFreq.get2dGovernor());
governor2d.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
GPUFreq.set2dGovernor(item, getActivity());
}
});
items.add(governor2d);
}
if (GPUFreq.hasGovernor()) {
SelectView governor = new SelectView();
governor.setTitle(getString(R.string.gpu_governor));
governor.setSummary(getString(R.string.gpu_governor_summary));
governor.setItems(GPUFreq.getAvailableGovernors());
governor.setItem(GPUFreq.getGovernor());
governor.setOnItemSelected(new SelectView.OnItemSelected() {
@Override
public void onItemSelected(SelectView selectView, int position, String item) {
GPUFreq.setGovernor(item, getActivity());
}
});
items.add(governor);
if (GPUFreq.hasTunables(governor.getValue())) {
DescriptionView tunables = new DescriptionView();
tunables.setTitle(getString(R.string.gpu_governor_tunables));
tunables.setSummary(getString(R.string.governor_tunables_summary));
tunables.setOnItemClickListener(new RecyclerViewItem.OnItemClickListener() {
@Override
public void onClick(RecyclerViewItem item) {
String governor = GPUFreq.getGovernor();
setForegroundText(governor);
mGPUGovernorTunableFragment.setError(getString(R.string.tunables_error, governor));
mGPUGovernorTunableFragment.setPath(GPUFreq.getTunables(GPUFreq.getGovernor()),
ApplyOnBootFragment.GPU);
showForeground();
}
});
items.add(tunables);
}
}
}
private void simpleGpuInit(List<RecyclerViewItem> items) {
List<RecyclerViewItem> simpleGpu = new ArrayList<>();
TitleView title = new TitleView();
title.setText(getString(R.string.simple_gpu_algorithm));
if (SimpleGPU.hasSimpleGpuEnable()) {
SwitchView enable = new SwitchView();
enable.setTitle(getString(R.string.simple_gpu_algorithm));
enable.setSummary(getString(R.string.simple_gpu_algorithm_summary));
enable.setChecked(SimpleGPU.isSimpleGpuEnabled());
enable.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
SimpleGPU.enableSimpleGpu(isChecked, getActivity());
}
});
simpleGpu.add(enable);
}
if (SimpleGPU.hasSimpleGpuLaziness()) {
SeekBarView laziness = new SeekBarView();
laziness.setTitle(getString(R.string.laziness));
laziness.setSummary(getString(R.string.laziness_summary));
laziness.setMax(10);
laziness.setProgress(SimpleGPU.getSimpleGpuLaziness());
laziness.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() {
@Override
public void onMove(SeekBarView seekBarView, int position, String value) {
}
@Override
public void onStop(SeekBarView seekBarView, int position, String value) {
SimpleGPU.setSimpleGpuLaziness(position, getActivity());
}
});
simpleGpu.add(laziness);
}
if (SimpleGPU.hasSimpleGpuRampThreshold()) {
SeekBarView rampThreshold = new SeekBarView();
rampThreshold.setTitle(getString(R.string.ramp_thresold));
rampThreshold.setSummary(getString(R.string.ramp_thresold_summary));
rampThreshold.setMax(10);
rampThreshold.setProgress(SimpleGPU.getSimpleGpuRampThreshold());
rampThreshold.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() {
@Override
public void onMove(SeekBarView seekBarView, int position, String value) {
}
@Override
public void onStop(SeekBarView seekBarView, int position, String value) {
SimpleGPU.setSimpleGpuRampThreshold(position, getActivity());
}
});
simpleGpu.add(rampThreshold);
}
if (simpleGpu.size() > 0) {
items.add(title);
items.addAll(simpleGpu);
}
}
private void adrenoIdlerInit(List<RecyclerViewItem> items) {
List<RecyclerViewItem> adrenoIdler = new ArrayList<>();
TitleView title = new TitleView();
title.setText(getString(R.string.adreno_idler));
if (AdrenoIdler.hasAdrenoIdlerEnable()) {
SwitchView enable = new SwitchView();
enable.setTitle(getString(R.string.adreno_idler));
enable.setSummary(getString(R.string.adreno_idler_summary));
enable.setChecked(AdrenoIdler.isAdrenoIdlerEnabled());
enable.addOnSwitchListener(new SwitchView.OnSwitchListener() {
@Override
public void onChanged(SwitchView switchView, boolean isChecked) {
AdrenoIdler.enableAdrenoIdler(isChecked, getActivity());
}
});
adrenoIdler.add(enable);
}
if (AdrenoIdler.hasAdrenoIdlerDownDiff()) {
SeekBarView downDiff = new SeekBarView();
downDiff.setTitle(getString(R.string.down_differential));
downDiff.setSummary(getString(R.string.down_differential_summary));
downDiff.setMax(99);
downDiff.setProgress(AdrenoIdler.getAdrenoIdlerDownDiff());
downDiff.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() {
@Override
public void onMove(SeekBarView seekBarView, int position, String value) {
}
@Override
public void onStop(SeekBarView seekBarView, int position, String value) {
AdrenoIdler.setAdrenoIdlerDownDiff(position, getActivity());
}
});
adrenoIdler.add(downDiff);
}
if (AdrenoIdler.hasAdrenoIdlerIdleWait()) {
SeekBarView idleWait = new SeekBarView();
idleWait.setTitle(getString(R.string.idle_wait));
idleWait.setSummary(getString(R.string.idle_wait_summary));
idleWait.setMax(99);
idleWait.setProgress(AdrenoIdler.getAdrenoIdlerIdleWait());
idleWait.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() {
@Override
public void onMove(SeekBarView seekBarView, int position, String value) {
}
@Override
public void onStop(SeekBarView seekBarView, int position, String value) {
AdrenoIdler.setAdrenoIdlerIdleWait(position, getActivity());
}
});
adrenoIdler.add(idleWait);
}
if (AdrenoIdler.hasAdrenoIdlerIdleWorkload()) {
SeekBarView idleWorkload = new SeekBarView();
idleWorkload.setTitle(getString(R.string.workload));
idleWorkload.setSummary(getString(R.string.workload_summary));
idleWorkload.setMax(10);
idleWorkload.setMin(1);
idleWorkload.setProgress(AdrenoIdler.getAdrenoIdlerIdleWorkload() - 1);
idleWorkload.setOnSeekBarListener(new SeekBarView.OnSeekBarListener() {
@Override
public void onMove(SeekBarView seekBarView, int position, String value) {
}
@Override
public void onStop(SeekBarView seekBarView, int position, String value) {
AdrenoIdler.setAdrenoIdlerIdleWorkload(position + 1, getActivity());
}
});
adrenoIdler.add(idleWorkload);
}
if (adrenoIdler.size() > 0) {
items.add(title);
items.addAll(adrenoIdler);
}
}
@Override
protected void refresh() {
super.refresh();
if (m2dCurFreq != null) {
int freq = GPUFreq.get2dCurFreq();
float maxFreq = GPUFreq.get2dAvailableFreqs().get(GPUFreq.get2dAvailableFreqs().size() - 1);
m2dCurFreq.setText((freq / 1000000) + getString(R.string.mhz));
float per = (float) freq / maxFreq * 100f;
m2dCurFreq.addPercentage(Math.round(per > 100 ? 100 : per < 0 ? 0 : per));
}
if (mCurFreq != null) {
int load = -1;
String text = "";
if (GPUFreq.hasBusy()) {
load = GPUFreq.getBusy();
load = load > 100 ? 100 : load < 0 ? 0 : load;
text += load + "% - ";
}
int freq = GPUFreq.getCurFreq();
float maxFreq = GPUFreq.getAvailableFreqs().get(GPUFreq.getAvailableFreqs().size() - 1);
text += freq / GPUFreq.getCurFreqOffset() + getString(R.string.mhz);
mCurFreq.setText(text);
float per = (float) freq / maxFreq * 100f;
mCurFreq.addPercentage(load >= 0 ? load : Math.round(per > 100 ? 100 : per < 0 ? 0 : per));
}
}
}