我有一个非常简单的在Android上运行的OpenGL ES应用程序 - 它只是加载一个纹理图集,然后在预定位置绘制一堆瓷砖
它基于本教程:http://androidblog.reindustries.com/a-real-open-gl-es-2-0-2d-tutorial-part-1/
渲染大约10秒后,CPU增加得相当快(如图所示),渲染每帧所需的时间从大约1ms增加到大约14ms(在我的Nexus 5上运行)
我在onDrawFrame
方法中对所有内容进行了计时,这完全是GLES20.glDrawElements
的错误
我的整个渲染方法是:
GLES20.glUseProgram(ShaderTools.sp_Image);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
int mPositionHandle = GLES20.glGetAttribLocation(ShaderTools.sp_Image, "vPosition");
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);
GLES20.glEnableVertexAttribArray(mPositionHandle);
int mTexCoordLoc = GLES20.glGetAttribLocation(ShaderTools.sp_Image, "a_texCoord");
GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 0, uvBuffer);
GLES20.glEnableVertexAttribArray(mTexCoordLoc);
int mtrxhandle = GLES20.glGetUniformLocation(ShaderTools.sp_Image, "uMVPMatrix");
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, mtrxProjectionAndView, 0);
int mSamplerLoc = GLES20.glGetUniformLocation(ShaderTools.sp_Image, "s_texture");
GLES20.glUniform1i(mSamplerLoc, 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
如果有人能够解释可能造成这种情况的原因,以及如何纠正它,那么我将非常感激: - )
答案 0 :(得分:1)
可能的解释是移动设备节省CPU功率以节省电池电量。 设备可能会发现您使用的CPU非常少,因此为了节省电量,它会降低CPU功耗。 我不记得曾经亲眼目睹过这种现象,但我知道它存在,不确定是否就是这种情况。
编辑:在这种情况下,您可以测量电池使用量是否与CPU使用率负相关。
答案 1 :(得分:1)
Nexus5基于高通芯片组,拥有Adreno 330 GPU。
如果您的应用程序图像密集型/没有fps限制器/渲染(巨大的)原始分辨率(因此不使用hardware scaler),高通芯片组可以快速控制GPU频率。
所以可能发生的事情是GPU频率受到限制,然后你会看到一个高CPU使用率,表示帧结束时“CPU等待GPU”。
CPU也可能受到限制,但根据我的经验,由于DVFS,这种情况往往发生在三星手机上,对Nexus来说并不多......
好消息是,实际存在监控当前CPU和工具的工具。高通设备上的GPU频率,称为Trepn Profiler,您可以在非root设备上使用它。
因此,您应该安装此工具,将其配置为显示GPU频率和CPU0频率作为叠加,然后启动您的应用程序,您将能够实时查看GPU和/或CPU如何随时间受到限制。
额外注意事项:手机充电时,节流会更快发生。