No segfault on OpenGL initialization failure but nice error screen.

This commit is contained in:
Matthias Koefferlein 2020-12-28 00:09:27 +01:00
parent 70dcc92640
commit a0d05753ad
5 changed files with 144 additions and 6 deletions

View File

@ -243,7 +243,84 @@
</widget>
</item>
<item>
<widget class="lay::D25ViewWidget" name="d25_view"/>
<widget class="QStackedWidget" name="gl_stack">
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="lay::D25ViewWidget" name="d25_view"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTextBrowser" name="error_text">
<property name="palette">
<palette>
<active>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>213</green>
<blue>213</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>213</green>
<blue>213</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>239</red>
<green>239</green>
<blue>239</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_2">

View File

@ -50,6 +50,9 @@ D25View::D25View (QWidget *parent)
connect (mp_ui->fit_bottom, SIGNAL (clicked ()), this, SLOT (fit_button_clicked ()));
connect (mp_ui->zoom_slider, SIGNAL (valueChanged (int)), this, SLOT (scale_slider_changed (int)));
connect (mp_ui->d25_view, SIGNAL (scale_factor_changed (double)), this, SLOT (scale_factor_changed (double)));
connect (mp_ui->d25_view, SIGNAL (init_failed ()), this, SLOT (init_failed ()));
mp_ui->gl_stack->setCurrentIndex (0);
}
D25View::~D25View ()
@ -65,6 +68,13 @@ static QString scale_factor_to_string (double f)
return s;
}
void
D25View::init_failed ()
{
mp_ui->error_text->setPlainText (tl::to_qstring (mp_ui->d25_view->error ()));
mp_ui->gl_stack->setCurrentIndex (1);
}
void
D25View::scale_slider_changed (int value)
{

View File

@ -58,6 +58,7 @@ private slots:
void fit_button_clicked ();
void scale_factor_changed (double f);
void scale_slider_changed (int value);
void init_failed ();
private:
Ui::D25View *mp_ui;

View File

@ -36,6 +36,9 @@
#include <QWheelEvent>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QImage>
#include <QPainter>
#include <QOpenGLTexture>
#include "math.h"
@ -186,7 +189,7 @@ private:
D25ViewWidget::D25ViewWidget (QWidget *parent)
: QOpenGLWidget (parent),
m_shapes_program (0)
m_shapes_program (0), m_gridplane_program (0)
{
QSurfaceFormat format;
format.setDepthBufferSize (24);
@ -694,6 +697,39 @@ static std::pair<double, double> find_grid (double v)
void
D25ViewWidget::initializeGL ()
{
tl_assert (m_shapes_program == 0);
tl_assert (m_gridplane_program == 0);
bool error = false;
try {
do_initialize_gl ();
} catch (tl::Exception &ex) {
m_error = ex.msg ();
error = true;
} catch (std::exception &ex) {
m_error = ex.what ();
error = true;
} catch (...) {
m_error = "(unspecific error)";
error = true;
}
if (error) {
delete m_shapes_program;
m_shapes_program = 0;
delete m_gridplane_program;
m_gridplane_program = 0;
emit init_failed ();
}
}
void
D25ViewWidget::do_initialize_gl ()
{
QOpenGLFunctions::initializeOpenGLFunctions();
@ -824,8 +860,8 @@ D25ViewWidget::initializeGL ()
void
D25ViewWidget::paintGL ()
{
const qreal retinaScale = devicePixelRatio ();
glViewport (0, 0, width () * retinaScale, height () * retinaScale);
const qreal retina_scale = devicePixelRatio ();
glViewport (0, 0, width () * retina_scale, height () * retina_scale);
QColor c = mp_view->background_color ();
float foreground_rgb = (c.green () > 128 ? 0.0f : 1.0f);
@ -835,6 +871,12 @@ D25ViewWidget::paintGL ()
glClearColor (float (c.red ()) / 255.0f, float (c.green ()) / 255.0f, float (c.blue ()) / 255.0f, 1.0);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
const int positions = 0;
if (! m_shapes_program || ! m_gridplane_program) {
return;
}
QMatrix4x4 scene_trans, scene_trans_wo_y;
// provide the displacement and scaling (in this order!)
@ -846,8 +888,6 @@ D25ViewWidget::paintGL ()
scene_trans_wo_y = scene_trans;
scene_trans_wo_y.translate (QVector3D (0.0, -m_displacement.y (), 0.0));
const int positions = 0;
m_shapes_program->bind ();
// draw the actual layout

View File

@ -104,8 +104,14 @@ public:
refresh ();
}
const std::string &error () const
{
return m_error;
}
signals:
void scale_factor_changed (double f);
void init_failed ();
protected:
virtual void camera_changed ();
@ -119,6 +125,7 @@ private:
std::auto_ptr<D25InteractionMode> mp_mode;
QOpenGLShaderProgram *m_shapes_program, *m_gridplane_program;
std::string m_error;
double m_scale_factor;
QVector3D m_displacement;
lay::LayoutView *mp_view;
@ -126,9 +133,11 @@ private:
double m_zmin, m_zmax;
std::list<chunks_type> m_vertex_chunks;
std::list<chunks_type> m_normals_chunks;
struct LayerInfo {
const chunks_type *vertex_chunk;
const chunks_type *normals_chunk;
GLfloat color [4];
};
@ -138,6 +147,7 @@ private:
void paintGL ();
void resizeGL (int w, int h);
void do_initialize_gl ();
bool prepare_view();
void render_layout (D25ViewWidget::chunks_type &chunks, const db::Layout &layout, const db::Cell &cell, unsigned int layer, double zstart, double zstop);
void render_polygon (D25ViewWidget::chunks_type &chunks, const db::Polygon &poly, double dbu, double zstart, double zstop);