для научной задачи на экране должны отображаться мерцающие области со стабильной частотой (макс. 60 Гц). Я попытался добиться стабильной визуализации стимула с помощью Qt 5.6.
Согласно этому запись в блоге и во многих других онлайн-рекомендациях я реализовал три различных подхода: наследование от класса QWindow, класса QOpenGLWindow и класса QRasterWindow. Я хотел получить преимущество от vsync и избежать использования QTimer.
Мерцающая область может быть отображена. Также стабильный период времени между кадрами был измерен с 16 до 17 мс.
Но каждые несколько секунд обнаруживаются пропущенные кадры. Очень хорошо видно, что нет устойчивой визуализации стимула. Тот же эффект происходит на всех трех подходах.
Правильно ли я реализовал свой код или существуют лучшие решения? Если код соответствует своему назначению, должен ли я считать, что это аппаратная проблема? Может ли быть так сложно отобразить простую мерцающую область?
Большое спасибо за помощь!
В качестве примера вы можете увидеть мой код для класса QWindow здесь:
Window::Window(QWindow *parent)
: m_context(0)
, m_paintDevice(0)
, m_bFlickerState(true){
setSurfaceType(QSurface::OpenGLSurface);
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setSwapInterval(1);
this->setFormat(format);
m_context.setFormat(format);
m_context.create();}
render()
Функция, которая вызывается перезаписанными функциями событий:
void Window::render(){
//calculating exposed time between frames
m_t1 = QTime::currentTime();
int curDelta = m_t0.msecsTo(m_t1);
m_t0 = m_t1;
qDebug()<< curDelta;
m_context.makeCurrent(this);
if (!m_paintDevice)
m_paintDevice = new QOpenGLPaintDevice;
if (m_paintDevice->size() != size())
m_paintDevice->setSize(size());
QPainter p(m_paintDevice);
// draw using QPainter
if(m_bFlickerState){
p.setBrush(Qt::white);
p.drawRect(0,0,this->width(),this->height());
}
p.end();
m_bFlickerState = !m_bFlickerState;
m_context.swapBuffers(this);
// animate continuously: schedule an update
QCoreApplication::postEvent( this, new QEvent(QEvent::UpdateRequest));}
Мне помогли некоторые эксперты с форума qt. Вы можете следить за всем обсуждением Вот. В конце концов, это был результат:
«V-синхронизация сложна;) В основном она борется с присущей системе шумностью. Если на выходе отображается 16-17 мс, тогда это проблема. 17 мс — это слишком. Это пропуск, который вы видите.
Несколько вещей, чтобы уменьшить этот шум:
Не имеет прямого отношения, но это сделает ваш код чище:
Применяя эти биты, я смог убрать пропуск из вашего примера. Обратите внимание, что пропуск будут происходят в некоторых обстоятельствах, например когда вы перемещаете / изменяете размер окна или когда ОС / другие приложения заняты чем-то. Вы не можете это контролировать.
«
Других решений пока нет …