<commit_before>

// Glew include
#include <GL/glew.h>

// TnzCore includes
#include "tgl.h"

// Qt includes
#include <QCoreApplication>
#include <QThread>
#include <QDateTime>

#include <QGLPixelBuffer>
#include <QGLFramebufferObject>
#include <QGLShaderProgram>

// STD includes
#include <map>
#include <memory>

#include "stdfx/shadingcontext.h"

//*****************************************************************
//    Local Namespace stuff
//*****************************************************************

namespace {

typedef std::unique_ptr<QGLPixelBuffer> QGLPixelBufferP;
typedef std::unique_ptr<QGLFramebufferObject> QGLFramebufferObjectP;
typedef std::unique_ptr<QGLShaderProgram> QGLShaderProgramP;

struct CompiledShader {
  QGLShaderProgramP m_program;
  QDateTime m_lastModified;

public:
  CompiledShader() {}
  CompiledShader(const CompiledShader &) { assert(!m_program.get()); }
};

}  // namespace

//*****************************************************************
//    ShadingContext::Imp  definition
//*****************************************************************

struct ShadingContext::Imp {
  QGLPixelBufferP m_pixelBuffer;  //!< OpenGL context.
  QGLFramebufferObjectP m_fbo;    //!< Output buffer.

  std::map<QString,
           CompiledShader>
      m_shaderPrograms;  //!< Shader Programs stored in the context.
                         //!  \warning   Values have \p unique_ptr members.
public:
  Imp();

  static QGLFormat format();

  void initMatrix(int lx, int ly);

private:
  // Not copyable
  Imp(const Imp &);
  Imp &operator=(const Imp &);
};

//--------------------------------------------------------

ShadingContext::Imp::Imp()
    : m_pixelBuffer(new QGLPixelBuffer(1, 1, format())) {}

//--------------------------------------------------------

QGLFormat ShadingContext::Imp::format() {
  QGLFormat fmt;

#ifdef MACOSX
  fmt.setVersion(3, 2);
  fmt.setProfile(QGLFormat::CompatibilityProfile);
#endif

  return fmt;
}

//--------------------------------------------------------

void ShadingContext::Imp::initMatrix(int lx, int ly) {
  glViewport(0, 0, lx, ly);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, lx, 0, ly);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

//*****************************************************************
//    ShadingContext  implementation
//*****************************************************************

ShadingContext::ShadingContext() : m_imp(new Imp) {
  makeCurrent();
  glewExperimental = GL_TRUE;
  glewInit();
  doneCurrent();
}

//--------------------------------------------------------

ShadingContext::~ShadingContext() {}

//--------------------------------------------------------

ShadingContext::Support ShadingContext::support() {
  return !QGLPixelBuffer::hasOpenGLPbuffers()
             ? NO_PIXEL_BUFFER
             : !QGLShaderProgram::hasOpenGLShaderPrograms() ? NO_SHADERS : OK;
}

//--------------------------------------------------------

bool ShadingContext::isValid() const { return m_imp->m_pixelBuffer->isValid(); }

//--------------------------------------------------------
/*
QGLFormat ShadingContext::defaultFormat(int channelsSize)
{
  QGL::FormatOptions opts =
    QGL::SingleBuffer     |
    QGL::NoAccumBuffer    |
    QGL::NoDepthBuffer    |                           // I guess it could be
necessary to let at least
    QGL::NoOverlay        |                           // the depth buffer
enabled... Fragment shaders could
    QGL::NoSampleBuffers  |                           // use it...
    QGL::NoStencilBuffer  |
    QGL::NoStereoBuffers;

  QGLFormat fmt(opts);
  fmt.setDirectRendering(true);                       // Just to be explicit -
USE HARDWARE ACCELERATION

  fmt.setRedBufferSize(channelsSize);
  fmt.setGreenBufferSize(channelsSize);
  fmt.setBlueBufferSize(channelsSize);
  fmt.setAlphaBufferSize(channelsSize);

  // TODO: 64-bit mode should be settable here

  return fmt;
}
*/
//--------------------------------------------------------

void ShadingContext::makeCurrent() { m_imp->m_pixelBuffer->makeCurrent(); }

//--------------------------------------------------------

void ShadingContext::doneCurrent() { m_imp->m_pixelBuffer->doneCurrent(); }

//--------------------------------------------------------

void ShadingContext::resize(int lx, int ly,
                            const QGLFramebufferObjectFormat &fmt) {
  if (m_imp->m_fbo.get() && m_imp->m_fbo->width() == lx &&
      m_imp->m_fbo->height() == ly && m_imp->m_fbo->format() == fmt)
    return;

  if (lx == 0 || ly == 0) {
    m_imp->m_fbo.reset(0);
  } else {
    m_imp->m_fbo.reset(new QGLFramebufferObject(lx, ly, fmt));
    assert(m_imp->m_fbo->isValid());

    m_imp->m_fbo->bind();
  }
}

//--------------------------------------------------------

QGLFramebufferObjectFormat ShadingContext::format() const {
  QGLFramebufferObject *fbo = m_imp->m_fbo.get();
  return fbo ? m_imp->m_fbo->format() : QGLFramebufferObjectFormat();
}
<commit_msg>change to move thread before destructor called (#702)<commit_after>

// Glew include
#include <GL/glew.h>

// TnzCore includes
#include "tgl.h"

// Qt includes
#include <QCoreApplication>
#include <QThread>
#include <QDateTime>

#include <QGLPixelBuffer>
#include <QGLFramebufferObject>
#include <QGLShaderProgram>
#include <QOpenGLContext>

// STD includes
#include <map>
#include <memory>

#include "stdfx/shadingcontext.h"

//*****************************************************************
//    Local Namespace stuff
//*****************************************************************

namespace {

typedef std::unique_ptr<QGLPixelBuffer> QGLPixelBufferP;
typedef std::unique_ptr<QGLFramebufferObject> QGLFramebufferObjectP;
typedef std::unique_ptr<QGLShaderProgram> QGLShaderProgramP;

struct CompiledShader {
  QGLShaderProgramP m_program;
  QDateTime m_lastModified;

public:
  CompiledShader() {}
  CompiledShader(const CompiledShader &) { assert(!m_program.get()); }
};

}  // namespace

//*****************************************************************
//    ShadingContext::Imp  definition
//*****************************************************************

struct ShadingContext::Imp {
  QGLPixelBufferP m_pixelBuffer;  //!< OpenGL context.
  QGLFramebufferObjectP m_fbo;    //!< Output buffer.

  std::map<QString,
           CompiledShader>
      m_shaderPrograms;  //!< Shader Programs stored in the context.
                         //!  \warning   Values have \p unique_ptr members.
public:
  Imp();

  static QGLFormat format();

  void initMatrix(int lx, int ly);

private:
  // Not copyable
  Imp(const Imp &);
  Imp &operator=(const Imp &);
};

//--------------------------------------------------------

ShadingContext::Imp::Imp()
    : m_pixelBuffer(new QGLPixelBuffer(1, 1, format())) {}

//--------------------------------------------------------

QGLFormat ShadingContext::Imp::format() {
  QGLFormat fmt;

#ifdef MACOSX
  fmt.setVersion(3, 2);
  fmt.setProfile(QGLFormat::CompatibilityProfile);
#endif

  return fmt;
}

//--------------------------------------------------------

void ShadingContext::Imp::initMatrix(int lx, int ly) {
  glViewport(0, 0, lx, ly);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, lx, 0, ly);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
}

//*****************************************************************
//    ShadingContext  implementation
//*****************************************************************

ShadingContext::ShadingContext() : m_imp(new Imp) {
  makeCurrent();
  glewExperimental = GL_TRUE;
  glewInit();
  doneCurrent();
}

//--------------------------------------------------------

ShadingContext::~ShadingContext() {
#ifdef MACOSX
  // Destructor of QGLPixelBuffer calls QOpenGLContext::makeCurrent() internally,
  // so the current thread must be the owner of QGLPixelBuffer context,
  // when the destructor of m_imp->m_context is called.

  m_imp->m_pixelBuffer->context()->contextHandle()->moveToThread(QThread::currentThread());
#endif
}

//--------------------------------------------------------

ShadingContext::Support ShadingContext::support() {
  return !QGLPixelBuffer::hasOpenGLPbuffers()
             ? NO_PIXEL_BUFFER
             : !QGLShaderProgram::hasOpenGLShaderPrograms() ? NO_SHADERS : OK;
}

//--------------------------------------------------------

bool ShadingContext::isValid() const { return m_imp->m_pixelBuffer->isValid(); }

//--------------------------------------------------------
/*
QGLFormat ShadingContext::defaultFormat(int channelsSize)
{
  QGL::FormatOptions opts =
    QGL::SingleBuffer     |
    QGL::NoAccumBuffer    |
    QGL::NoDepthBuffer    |                           // I guess it could be
necessary to let at least
    QGL::NoOverlay        |                           // the depth buffer
enabled... Fragment shaders could
    QGL::NoSampleBuffers  |                           // use it...
    QGL::NoStencilBuffer  |
    QGL::NoStereoBuffers;

  QGLFormat fmt(opts);
  fmt.setDirectRendering(true);                       // Just to be explicit -
USE HARDWARE ACCELERATION

  fmt.setRedBufferSize(channelsSize);
  fmt.setGreenBufferSize(channelsSize);
  fmt.setBlueBufferSize(channelsSize);
  fmt.setAlphaBufferSize(channelsSize);

  // TODO: 64-bit mode should be settable here

  return fmt;
}
*/
//--------------------------------------------------------

void ShadingContext::makeCurrent() {
#ifdef MACOSX
  m_imp->m_pixelBuffer->context()->contextHandle()->moveToThread(QThread::currentThread());
#endif
  m_imp->m_pixelBuffer->makeCurrent();
}

//--------------------------------------------------------

void ShadingContext::doneCurrent() {
#ifdef MACOSX
  m_imp->m_pixelBuffer->context()->contextHandle()->moveToThread(0);
#endif
  m_imp->m_pixelBuffer->doneCurrent();
}

//--------------------------------------------------------

void ShadingContext::resize(int lx, int ly,
                            const QGLFramebufferObjectFormat &fmt) {
  if (m_imp->m_fbo.get() && m_imp->m_fbo->width() == lx &&
      m_imp->m_fbo->height() == ly && m_imp->m_fbo->format() == fmt)
    return;

  if (lx == 0 || ly == 0) {
    m_imp->m_fbo.reset(0);
  } else {
    m_imp->m_fbo.reset(new QGLFramebufferObject(lx, ly, fmt));
    assert(m_imp->m_fbo->isValid());

    m_imp->m_fbo->bind();
  }
}

//--------------------------------------------------------

QGLFramebufferObjectFormat ShadingContext::format() const {
  QGLFramebufferObject *fbo = m_imp->m_fbo.get();
  return fbo ? m_imp->m_fbo->format() : QGLFramebufferObjectFormat();
}

{'fraction_non_alphanumeric': 0.3001320505564988, 'fraction_numerical': 0.003018298434257687, 'mean_word_length': 2.371383147853736, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5511506', 'n_tokens_mistral': 3074, 'n_tokens_neox': 2975, 'n_words': 563}