Я обнаружил кое-что интересное на Android Gl20, которое мне удалось воспроизвести в "Hello Gl20" Android Studio, и я хотел бы услышать любые мнения по этому вопросу.
В двух словах, на S5 (и других устройствах) тратится ~ 15 мс при первом использовании функции gl * (я бы сказал, что контекст gl, но я просто хочу показать факты, а не свою интерпретацию).
Способ, которым я получил этот тролль мс, чтобы показать его лицо: В GLSufaceView Renderer.onDraw (на GLThread) я называю нативный забавный c GL2JNILib.step (этот dr aws простой треугольник) 2 раза и У каждого звонка свой идентификатор (int). Для первого вызова идентификатор равен 0, а для второго - 1. В собственной функции я настроил простое измерение времени на основе CLOCK_MONOTONI C. Первый вызов (вызов с идентификатором 0) занимает 16 мс, а второй вызов занимает (вызов с идентификатором 1) - 0 мс. И эта вещь повторяет следующий кадр как-то так же и т. Д.
Кроме того, в собственной функции GL2JNILib.step я объединяю команды в блоки и измеряю эти блоки по отдельности (без изменения порядка выполнения) и получается, что те ~ 15 мс, которые потрачены впустую, теряются в блоке очистки.
Вот некоторые фрагменты модификации:
GL2JNIView. java
....
private static class Renderer implements GLSurfaceView.Renderer {
public void onDrawFrame(GL10 gl) {
GL2JNILib.step(0);
GL2JNILib.step(1);
}
...
ATime.h (простой таймер - заголовок)
#ifndef TIME_H__
#define TIME_H__
#include "ATypes.h"
namespace ATime {
void init ();
u64 ms ();
f64 s();
void waste (u64 const wasteMs);
};
ATime. cpp (простой таймер - реализация)
#include "ATime.h"
#include <time.h>
#define CLOCK CLOCK_MONOTONIC
namespace ATime {
long mStartSec = 0;
void init() {
struct timespec res;
clock_gettime(CLOCK, &res);
mStartSec = res.tv_sec;
}
u64 ms() {
struct timespec res;
clock_gettime(CLOCK, &res);
u64 ms = static_cast<u64>(res.tv_sec - mStartSec) * 1000 + res.tv_nsec / 1000000;
return ms;
}
f64 s() {
struct timespec res;
clock_gettime(CLOCK, &res);
f64 ms = 1000.0 * (res.tv_sec - mStartSec) + (f64) res.tv_nsec / 1000000.0;
return ms / 1000.0;
}
void waste(u64 const wasteMs) {
f64 t = s();
f64 e = t + static_cast<f64>(wasteMs) / 1000.0f;
while (t < e){
t = s ();
}
}
}
и в gl_code. cpp Я изменил функцию renderFrame (), чтобы получить id (int), и теперь она выглядит примерно так:
...
class MeasureBlock {
public:
MeasureBlock (i32 id, char const *const tag) : mId(id), mName (tag){
mStart = ATime::ms();
}
~MeasureBlock(){
auto duration = ATime::ms() - mStart;
LOGI ("%s - %d duration %d", mName, mId, static_cast<u32>(duration));
}
protected:
u64 mStart;
char const * const mName;
i32 mId;
};
void renderFrame(i32 id) {
MeasureBlock total (id, "total");
static float grey;
grey += 0.01f;
if (grey > 1.0f) {
grey = 0.0f;
}
{
MeasureBlock clear (id, "clear");
glClearColor(grey, grey, grey, 1.0f);
checkGlError("glClearColor");
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
checkGlError("glClear");
}
{
MeasureBlock actualDraw(id, "actualDraw");
glUseProgram(gProgram);
checkGlError("glUseProgram");
glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
checkGlError("glVertexAttribPointer");
glEnableVertexAttribArray(gvPositionHandle);
checkGlError("glEnableVertexAttribArray");
glDrawArrays(GL_TRIANGLES, 0, 3);
checkGlError("glDrawArrays");
}
}
...
Вот результат этого волхва c afair:
...
clear - 0 duration 15
actualDraw - 0 duration 0
total - 0 duration 15
clear - 1 duration 0
actualDraw - 1 duration 0
total - 1 duration 0
...
Стоит отметить, что значение clear - 0 продолжительности, выглядит так: 13, 16, 15..15, 18 и так далее:)
Мне кажется, что контекст gl заблокирован в другой поток и GLThred должен ждать, пока не освободится контекст gl. Эта так называемая «теория», кажется, подтверждается синхронизацией на основе CLOCK_THREAD_CPUTIME_ID и отсутствием тролля в мс, показывающего его лицо в GLThread (если измерено без времени простоя или сна - в отличие от реального мира). Я имею в виду все измерения, как ожидалось, 0 мс. Я не могу обернуться, как избавиться от этого тролля, потому что осталось немного.
Забавно, на экране больше ничего нет, активность на весь экран, а 16 мс - много времени для всего этого ничего.
Есть ли у кого-нибудь какие-либо идеи, как избавиться от этих потраченных впустую мс, выкинуть мисс тролль из своего рода речи, или может принести любой тип и / или форму света к выпуск?
С большим ожиданием и признательностью,
Жан-Артур Деда.