Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 47 additions & 5 deletions src/lib/app/RvCommon/GLView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,41 @@ namespace Rv

} // namespace

//
// Helper function to query actual OpenGL framebuffer format
// Works around Qt bug (qcocoaglcontext.mm:267) where it divides NSOpenGLPFAColorSize by 4
// instead of 3, causing it to report 8-8-8-2 when the actual format is 10-10-10-2
//
namespace
{
QSurfaceFormat queryActualFormat(QOpenGLContext* context, const QSurfaceFormat& qtFormat)
{
QSurfaceFormat actualFormat = qtFormat;

if (!context || !context->isValid())
return actualFormat;

// Query OpenGL directly for actual framebuffer bit depths
GLint redBits = 0, greenBits = 0, blueBits = 0, alphaBits = 0;
glGetIntegerv(GL_RED_BITS, &redBits);
glGetIntegerv(GL_GREEN_BITS, &greenBits);
glGetIntegerv(GL_BLUE_BITS, &blueBits);
glGetIntegerv(GL_ALPHA_BITS, &alphaBits);

// Update format with actual values from OpenGL
if (redBits > 0)
actualFormat.setRedBufferSize(redBits);
if (greenBits > 0)
actualFormat.setGreenBufferSize(greenBits);
if (blueBits > 0)
actualFormat.setBlueBufferSize(blueBits);
if (alphaBits >= 0)
actualFormat.setAlphaBufferSize(alphaBits);

return actualFormat;
}
} // namespace

GLView::GLView(QWidget* parent, QOpenGLContext* sharedContext, RvDocument* doc, bool stereo, bool vsync, bool doubleBuffer, int red,
int green, int blue, int alpha, bool noResize)
: QOpenGLWidget(parent)
Expand Down Expand Up @@ -156,6 +191,8 @@ namespace Rv
connect(&m_eventProcessingTimer, SIGNAL(timeout()), this, SLOT(eventProcessingTimeout()));
}

QSurfaceFormat GLView::actualFormat() const { return m_actualFormat; }

GLView::~GLView()
{
// delete m_frameBuffer;
Expand Down Expand Up @@ -262,11 +299,17 @@ namespace Rv
}

// NOTE_QT6: QGLFormat is deprecated. Using QSurfaceFormat now.
QSurfaceFormat f = context()->format();
QSurfaceFormat maybeBuggyQtFormat = context()->format();

// Get the ACTUAL format by querying OpenGL directly (works around Qt bug)
QSurfaceFormat f = queryActualFormat(context(), maybeBuggyQtFormat);

// Store the actual format so it can be retrieved via actualFormat()
m_actualFormat = f;

#ifndef PLATFORM_DARWIN
//
// Doesn't work on OS X
// Check if we got the requested format using ACTUAL OpenGL values
// (not Qt's potentially buggy reported values)
//
if (f.redBufferSize() != m_red && m_red != 0)
{
Expand Down Expand Up @@ -295,7 +338,7 @@ namespace Rv
// QMessageBox::AcceptRole); box.setIcon(QMessageBox::Critical);
// box.exec();
}
#endif

if (f.stencilBufferSize() == 0)
{
cout << "WARNING: no stencil buffer available" << endl;
Expand Down Expand Up @@ -592,7 +635,6 @@ namespace Rv
//
if (event->type() == QEvent::TabletPress && !isActiveWindow())
{
cerr << "activating window" << endl;
QEvent activateEvent(QEvent::WindowActivate);
//m_frameBuffer->translator().sendQTEvent(new QEvent(QEvent::WindowActivate));
session->setEventVideoDevice(videoDevice());
Expand Down
4 changes: 4 additions & 0 deletions src/lib/app/RvCommon/RvCommon/GLView.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ namespace Rv

QTGLVideoDevice* videoDevice() const { return m_videoDevice; }

// Get the actual OpenGL format (works around Qt bug where format() may be incorrect)
QSurfaceFormat actualFormat() const;

void stopProcessingEvents();

virtual bool event(QEvent*);
Expand Down Expand Up @@ -97,6 +100,7 @@ namespace Rv
bool m_stopProcessingEvents;
void* m_syncThreadData;
QOpenGLContext* m_sharedContext;
QSurfaceFormat m_actualFormat; // Actual format queried from OpenGL (corrects Qt bug)
};

} // namespace Rv
Expand Down
82 changes: 48 additions & 34 deletions src/lib/app/RvCommon/RvDocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ namespace Rv
}

// Create DiagnosticsView as a dockable widget (lazy initialization).
m_diagnosticsView = new DiagnosticsView(nullptr, m_glView->format());
m_diagnosticsView = new DiagnosticsView(nullptr, m_glView->actualFormat());

// Dockable to QMainWindow, not centralwidget.
m_diagnosticsDock = new QDockWidget(tr("Diagnostics"), this);
Expand Down Expand Up @@ -798,19 +798,29 @@ namespace Rv
size_t ow = centralWidget()->width();
size_t oh = centralWidget()->height();

// Add widget to layout and show FIRST - isValid() only returns true after widget is shown
m_stackedLayout->removeWidget(oldGLView);
m_stackedLayout->addWidget(newGLView);
m_glView = newGLView;
m_glView->show();
m_glView->setFocus(Qt::OtherFocusReason);

// Process events to trigger GL context creation and initializeGL()
QApplication::processEvents();

// Now check validity (after initialization has occurred)
if (!newGLView->isValid())
{
m_stackedLayout->removeWidget(newGLView);
delete newGLView;
newGLView = new GLView(this, view()->context(), this);
m_stackedLayout->addWidget(newGLView);
m_glView = newGLView;
m_glView->show();
m_glView->setFocus(Qt::OtherFocusReason);
resetGLPrefs = true;
}

m_stackedLayout->addWidget(newGLView);
m_stackedLayout->removeWidget(oldGLView);
m_glView = newGLView;
m_glView->show();
m_glView->setFocus(Qt::OtherFocusReason);

m_topViewToolBar->setDevice(m_glView->videoDevice());

bool same = m_session->outputVideoDevice() == m_session->controlVideoDevice();
Expand Down Expand Up @@ -848,15 +858,16 @@ namespace Rv

void RvDocument::setStereo(bool b)
{
const bool vsync = m_glView->format().swapInterval() == 1;
const bool stereo = m_glView->format().stereo();
QSurfaceFormat format = m_glView->actualFormat();
const bool vsync = format.swapInterval() == 1;
const bool stereo = format.stereo();
bool dbl = false;
if (m_glView->format().swapBehavior() == QSurfaceFormat::DoubleBuffer)
if (format.swapBehavior() == QSurfaceFormat::DoubleBuffer)
dbl = true;
const int red = m_glView->format().redBufferSize();
const int green = m_glView->format().greenBufferSize();
const int blue = m_glView->format().blueBufferSize();
const int alpha = m_glView->format().alphaBufferSize();
const int red = format.redBufferSize();
const int green = format.greenBufferSize();
const int blue = format.blueBufferSize();
const int alpha = format.alphaBufferSize();
if (b != stereo)
rebuildGLView(b, vsync, dbl, red, green, blue, alpha);
}
Expand All @@ -865,27 +876,29 @@ namespace Rv
{
if (m_vsyncDisabled)
return;
const bool vsync = m_glView->format().swapInterval() == 1;
const bool stereo = m_glView->format().stereo();
QSurfaceFormat format = m_glView->actualFormat();
const bool vsync = format.swapInterval() == 1;
const bool stereo = format.stereo();
bool dbl = false;
if (m_glView->format().swapBehavior() == QSurfaceFormat::DoubleBuffer)
if (format.swapBehavior() == QSurfaceFormat::DoubleBuffer)
dbl = true;
const int red = m_glView->format().redBufferSize();
const int green = m_glView->format().greenBufferSize();
const int blue = m_glView->format().blueBufferSize();
const int alpha = m_glView->format().alphaBufferSize();
const int red = format.redBufferSize();
const int green = format.greenBufferSize();
const int blue = format.blueBufferSize();
const int alpha = format.alphaBufferSize();
if (b != vsync)
rebuildGLView(stereo, b, dbl, red, green, blue, alpha);
}

void RvDocument::setDoubleBuffer(bool b)
{
bool vsync = m_glView->format().swapInterval() == 1;
const bool stereo = m_glView->format().stereo();
const int red = m_glView->format().redBufferSize();
const int green = m_glView->format().greenBufferSize();
const int blue = m_glView->format().blueBufferSize();
const int alpha = m_glView->format().alphaBufferSize();
QSurfaceFormat format = m_glView->actualFormat();
bool vsync = format.swapInterval() == 1;
const bool stereo = format.stereo();
const int red = format.redBufferSize();
const int green = format.greenBufferSize();
const int blue = format.blueBufferSize();
const int alpha = format.alphaBufferSize();

if (!b)
vsync = false;
Expand All @@ -895,15 +908,16 @@ namespace Rv

void RvDocument::setDisplayOutput(DisplayOutputType type)
{
const bool vsync = m_glView->format().swapInterval() == 1;
const bool stereo = m_glView->format().stereo();
QSurfaceFormat format = m_glView->actualFormat();
const bool vsync = format.swapInterval() == 1;
const bool stereo = format.stereo();
bool dbl = false;
if (m_glView->format().swapBehavior() == QSurfaceFormat::DoubleBuffer)
if (format.swapBehavior() == QSurfaceFormat::DoubleBuffer)
dbl = true;
int red = m_glView->format().redBufferSize();
int green = m_glView->format().greenBufferSize();
int blue = m_glView->format().blueBufferSize();
int alpha = m_glView->format().alphaBufferSize();
int red = format.redBufferSize();
int green = format.greenBufferSize();
int blue = format.blueBufferSize();
int alpha = format.alphaBufferSize();

switch (type)
{
Expand Down
Loading