blob: 91dd2362583c3c7fe793c461557dc5720f9549b6 [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080017#include <stdint.h>
18#include <limits.h>
19#include <sys/types.h>
20#include <math.h>
21
22#include <utils/threads.h>
23#include <utils/Errors.h>
24#include <utils/Log.h>
25
26#include <ui/PixelFormat.h>
27#include <ui/Rect.h>
28#include <ui/Region.h>
29#include <ui/DisplayInfo.h>
30#include <ui/ISurfaceComposer.h>
31#include <ui/ISurfaceFlingerClient.h>
32
33#include <pixelflinger/pixelflinger.h>
34
35#include "CPUGauge.h"
36
37namespace android {
38
39CPUGauge::CPUGauge( const sp<ISurfaceComposer>& composer,
40 nsecs_t interval,
41 int clock,
42 int refclock)
43 : Thread(false),
44 mInterval(interval), mClock(clock), mRefClock(refclock),
45 mReferenceTime(0),
46 mReferenceWorkingTime(0), mCpuUsage(0),
47 mRefIdleTime(0), mIdleTime(0)
48{
49 mFd = fopen("/proc/stat", "r");
50 setvbuf(mFd, NULL, _IONBF, 0);
51
52 mSession = SurfaceComposerClient::clientForConnection(
53 composer->createConnection()->asBinder());
54}
55
56CPUGauge::~CPUGauge()
57{
58 fclose(mFd);
59}
60
61const sp<SurfaceComposerClient>& CPUGauge::session() const
62{
63 return mSession;
64}
65
66void CPUGauge::onFirstRef()
67{
68 run("CPU Gauge");
69}
70
71status_t CPUGauge::readyToRun()
72{
73 LOGI("Starting CPU gauge...");
74 return NO_ERROR;
75}
76
77bool CPUGauge::threadLoop()
78{
79 DisplayInfo dinfo;
80 session()->getDisplayInfo(0, &dinfo);
81 sp<Surface> s(session()->createSurface(getpid(), 0, dinfo.w, 4, PIXEL_FORMAT_OPAQUE));
82 session()->openTransaction();
83 s->setLayer(INT_MAX);
84 session()->closeTransaction();
85
86 static const GGLfixed colors[4][4] = {
87 { 0x00000, 0x10000, 0x00000, 0x10000 },
88 { 0x10000, 0x10000, 0x00000, 0x10000 },
89 { 0x10000, 0x00000, 0x00000, 0x10000 },
90 { 0x00000, 0x00000, 0x00000, 0x10000 },
91 };
92
93 GGLContext* gl;
94 gglInit(&gl);
95 gl->activeTexture(gl, 0);
96 gl->disable(gl, GGL_TEXTURE_2D);
97 gl->disable(gl, GGL_BLEND);
98
99 const int w = dinfo.w;
100
101 while(!exitPending())
102 {
103 mLock.lock();
104 const float cpuUsage = this->cpuUsage();
105 const float totalCpuUsage = 1.0f - idle();
106 mLock.unlock();
107
108 Surface::SurfaceInfo info;
109 s->lock(&info);
110 GGLSurface fb;
111 fb.version = sizeof(GGLSurface);
112 fb.width = info.w;
113 fb.height = info.h;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700114 fb.stride = info.s;
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800115 fb.format = info.format;
116 fb.data = (GGLubyte*)info.bits;
117
118 gl->colorBuffer(gl, &fb);
119 gl->color4xv(gl, colors[3]);
120 gl->recti(gl, 0, 0, w, 4);
121 gl->color4xv(gl, colors[2]); // red
122 gl->recti(gl, 0, 0, int(totalCpuUsage*w), 2);
123 gl->color4xv(gl, colors[0]); // green
124 gl->recti(gl, 0, 2, int(cpuUsage*w), 4);
125
126 s->unlockAndPost();
127
128 usleep(ns2us(mInterval));
129 }
130
131 gglUninit(gl);
132 return false;
133}
134
135void CPUGauge::sample()
136{
137 if (mLock.tryLock() == NO_ERROR) {
138 const nsecs_t now = systemTime(mRefClock);
139 const nsecs_t referenceTime = now-mReferenceTime;
140 if (referenceTime >= mInterval) {
141 const float reftime = 1.0f / referenceTime;
142 const nsecs_t nowWorkingTime = systemTime(mClock);
143
144 char buf[256];
145 fgets(buf, 256, mFd);
146 rewind(mFd);
147 char *str = buf+5;
148 char const * const usermode = strsep(&str, " "); (void)usermode;
149 char const * const usernice = strsep(&str, " "); (void)usernice;
150 char const * const systemmode = strsep(&str, " ");(void)systemmode;
151 char const * const idle = strsep(&str, " ");
152 const nsecs_t nowIdleTime = atoi(idle) * 10000000LL;
153 mIdleTime = float(nowIdleTime - mRefIdleTime) * reftime;
154 mRefIdleTime = nowIdleTime;
155
156 const nsecs_t workingTime = nowWorkingTime - mReferenceWorkingTime;
157 const float newCpuUsage = float(workingTime) * reftime;
158 if (mCpuUsage != newCpuUsage) {
159 mCpuUsage = newCpuUsage;
160 mReferenceWorkingTime = nowWorkingTime;
161 mReferenceTime = now;
162 }
163 }
164 mLock.unlock();
165 }
166}
167
168
169}; // namespace android