Split SceneOpenGL into a concrete SceneOpenGL1 and SceneOpenGL2
SceneOpenGL turns into an abstract class with two concrete subclasses: * SceneOpenGL1 * SceneOpenGL2 It provides a factory method which first creates either the GLX or EGL backend which is passed to a static supported() method in the concrete sub classes. These method can test whether the backend is sufficient to be used for the OpenGL version in question. E.g. the OpenGL 2 scene checks whether the context is direct. The actual rendering is moved into the subclasses with specific OpenGL 1 and OpenGL 2 code. This should make the code more readable and requires less checks whether a Shader is bound. This is now known through the Scene: the OpenGL1 scene will never have a shader bound, the OpenGL2 scene will always have a shader bound. To make this more reliable the ShaderManager is extended by a disable method used by SceneOpenGL1 to ensure that the ShaderManager will never be used. This also obsoletes the need to read the KWin configuration whether legacy GL is enabled. The check is moved into the supported method of the OpenGL2 scene. REVIEW: 106357icc-effect-5.14.5
parent
db9368fc26
commit
5a6d9400b2
|
@ -191,13 +191,13 @@ void Compositor::slotCompositingOptionsInitialized()
|
|||
}
|
||||
#endif
|
||||
|
||||
m_scene = new SceneOpenGL(Workspace::self());
|
||||
m_scene = SceneOpenGL::createScene();
|
||||
|
||||
// TODO: Add 30 second delay to protect against screen freezes as well
|
||||
unsafeConfig.writeEntry("OpenGLIsUnsafe", false);
|
||||
unsafeConfig.sync();
|
||||
|
||||
if (!m_scene->initFailed())
|
||||
if (m_scene && !m_scene->initFailed())
|
||||
break; // -->
|
||||
delete m_scene;
|
||||
m_scene = NULL;
|
||||
|
|
|
@ -61,7 +61,6 @@ static int eglVersion;
|
|||
static QStringList glExtensions;
|
||||
static QStringList glxExtensions;
|
||||
static QStringList eglExtension;
|
||||
static bool legacyGl;
|
||||
|
||||
int glTextureUnitsCount;
|
||||
|
||||
|
@ -102,11 +101,7 @@ void initGL()
|
|||
QStringList glversioninfo = glversionstring.left(glversionstring.indexOf(' ')).split('.');
|
||||
while (glversioninfo.count() < 3)
|
||||
glversioninfo << "0";
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
legacyGl = false;
|
||||
#else
|
||||
KConfigGroup config(KGlobal::config(), "Compositing");
|
||||
legacyGl = config.readEntry<bool>("GLLegacy", false);
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
glVersion = MAKE_GL_VERSION(glversioninfo[0].toInt(), glversioninfo[1].toInt(), glversioninfo[2].toInt());
|
||||
#endif
|
||||
// Get list of supported OpenGL extensions
|
||||
|
@ -627,6 +622,16 @@ ShaderManager *ShaderManager::instance()
|
|||
return s_shaderManager;
|
||||
}
|
||||
|
||||
void ShaderManager::disable()
|
||||
{
|
||||
// for safety do a Cleanup first
|
||||
ShaderManager::cleanup();
|
||||
// create a new ShaderManager and set it to inited without calling init
|
||||
// that will ensure that the ShaderManager is not valid
|
||||
s_shaderManager = new ShaderManager();
|
||||
s_shaderManager->m_inited = true;
|
||||
}
|
||||
|
||||
void ShaderManager::cleanup()
|
||||
{
|
||||
delete s_shaderManager;
|
||||
|
@ -797,10 +802,6 @@ GLShader *ShaderManager::loadShaderFromCode(const QByteArray &vertexSource, cons
|
|||
|
||||
void ShaderManager::initShaders()
|
||||
{
|
||||
if (legacyGl) {
|
||||
kDebug(1212) << "OpenGL Shaders disabled by config option";
|
||||
return;
|
||||
}
|
||||
m_orthoShader = new GLShader(":/resources/scene-vertex.glsl", ":/resources/scene-fragment.glsl");
|
||||
if (m_orthoShader->isValid()) {
|
||||
pushShader(SimpleShader, true);
|
||||
|
|
|
@ -355,6 +355,15 @@ public:
|
|||
* @return a pointer to the ShaderManager instance
|
||||
**/
|
||||
static ShaderManager *instance();
|
||||
/**
|
||||
* @brief Ensures that the ShaderManager is disabled.
|
||||
*
|
||||
* Used only by an OpenGL 1 Scene which does not use OpenGL 2 Shaders.
|
||||
*
|
||||
* @internal
|
||||
* @since 4.10
|
||||
**/
|
||||
static void disable();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
|
11
options.cpp
11
options.cpp
|
@ -155,6 +155,7 @@ Options::Options(QObject *parent)
|
|||
, m_glDirect(Options::defaultGlDirect())
|
||||
, m_glStrictBinding(Options::defaultGlStrictBinding())
|
||||
, m_glStrictBindingFollowsDriver(Options::defaultGlStrictBindingFollowsDriver())
|
||||
, m_glLegacy(Options::defaultGlLegacy())
|
||||
, OpTitlebarDblClick(Options::defaultOperationTitlebarDblClick())
|
||||
, CmdActiveTitlebar1(Options::defaultCommandActiveTitlebar1())
|
||||
, CmdActiveTitlebar2(Options::defaultCommandActiveTitlebar2())
|
||||
|
@ -761,6 +762,15 @@ void Options::setGlStrictBindingFollowsDriver(bool glStrictBindingFollowsDriver)
|
|||
emit glStrictBindingFollowsDriverChanged();
|
||||
}
|
||||
|
||||
void Options::setGlLegacy(bool glLegacy)
|
||||
{
|
||||
if (m_glLegacy == glLegacy) {
|
||||
return;
|
||||
}
|
||||
m_glLegacy = glLegacy;
|
||||
emit glLegacyChanged();
|
||||
}
|
||||
|
||||
void Options::setElectricBorders(int borders)
|
||||
{
|
||||
if (electric_borders == borders) {
|
||||
|
@ -985,6 +995,7 @@ void Options::reloadCompositingSettings(bool force)
|
|||
if (!isGlStrictBindingFollowsDriver()) {
|
||||
setGlStrictBinding(config.readEntry("GLStrictBinding", Options::defaultGlStrictBinding()));
|
||||
}
|
||||
setGlLegacy(config.readEntry("GLLegacy", Options::defaultGlLegacy()));
|
||||
|
||||
m_xrenderSmoothScale = config.readEntry("XRenderSmoothScale", false);
|
||||
|
||||
|
|
13
options.h
13
options.h
|
@ -191,6 +191,10 @@ class Options : public QObject, public KDecorationOptions
|
|||
* If @c false @link glStrictBinding is set from a config value and not updated during scene initialization.
|
||||
**/
|
||||
Q_PROPERTY(bool glStrictBindingFollowsDriver READ isGlStrictBindingFollowsDriver WRITE setGlStrictBindingFollowsDriver NOTIFY glStrictBindingFollowsDriverChanged)
|
||||
/**
|
||||
* Whether legacy OpenGL should be used or OpenGL (ES) 2
|
||||
**/
|
||||
Q_PROPERTY(bool glLegacy READ isGlLegacy WRITE setGlLegacy NOTIFY glLegacyChanged)
|
||||
public:
|
||||
|
||||
Options(QObject *parent = NULL);
|
||||
|
@ -562,6 +566,9 @@ public:
|
|||
bool isGlStrictBindingFollowsDriver() const {
|
||||
return m_glStrictBindingFollowsDriver;
|
||||
}
|
||||
bool isGlLegacy() const {
|
||||
return m_glLegacy;
|
||||
}
|
||||
|
||||
// setters
|
||||
void setFocusPolicy(FocusPolicy focusPolicy);
|
||||
|
@ -624,6 +631,7 @@ public:
|
|||
void setGlDirect(bool glDirect);
|
||||
void setGlStrictBinding(bool glStrictBinding);
|
||||
void setGlStrictBindingFollowsDriver(bool glStrictBindingFollowsDriver);
|
||||
void setGlLegacy(bool glLegacy);
|
||||
|
||||
// default values
|
||||
static FocusPolicy defaultFocusPolicy() {
|
||||
|
@ -843,6 +851,9 @@ public:
|
|||
static bool defaultGlStrictBindingFollowsDriver() {
|
||||
return true;
|
||||
}
|
||||
static bool defaultGlLegacy() {
|
||||
return false;
|
||||
}
|
||||
static int defaultAnimationSpeed() {
|
||||
return 3;
|
||||
}
|
||||
|
@ -923,6 +934,7 @@ Q_SIGNALS:
|
|||
void glDirectChanged();
|
||||
void glStrictBindingChanged();
|
||||
void glStrictBindingFollowsDriverChanged();
|
||||
void glLegacyChanged();
|
||||
|
||||
private:
|
||||
void setElectricBorders(int borders);
|
||||
|
@ -966,6 +978,7 @@ private:
|
|||
bool m_glDirect;
|
||||
bool m_glStrictBinding;
|
||||
bool m_glStrictBindingFollowsDriver;
|
||||
bool m_glLegacy;
|
||||
|
||||
WindowOperation OpTitlebarDblClick;
|
||||
|
||||
|
|
320
scene_opengl.cpp
320
scene_opengl.cpp
|
@ -137,15 +137,10 @@ void OpenGLBackend::idle()
|
|||
* SceneOpenGL
|
||||
***********************************************/
|
||||
|
||||
SceneOpenGL::SceneOpenGL(Workspace* ws)
|
||||
SceneOpenGL::SceneOpenGL(Workspace* ws, OpenGLBackend *backend)
|
||||
: Scene(ws)
|
||||
, m_resetModelViewProjectionMatrix(true)
|
||||
, init_ok(false)
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
, m_backend(new EglOnXBackend())
|
||||
#else
|
||||
, m_backend(new GlxBackend())
|
||||
#endif
|
||||
, m_backend(backend)
|
||||
{
|
||||
if (m_backend->isFailed()) {
|
||||
return;
|
||||
|
@ -158,11 +153,13 @@ SceneOpenGL::SceneOpenGL(Workspace* ws)
|
|||
QTimer::singleShot(0, Workspace::self(), SLOT(fallbackToXRenderCompositing()));
|
||||
return;
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if (!hasGLExtension("GL_ARB_texture_non_power_of_two")
|
||||
&& !hasGLExtension("GL_ARB_texture_rectangle")) {
|
||||
kError(1212) << "GL_ARB_texture_non_power_of_two and GL_ARB_texture_rectangle missing";
|
||||
return; // error
|
||||
}
|
||||
#endif
|
||||
if (glPlatform->isMesaDriver() && glPlatform->mesaVersion() < kVersionNumber(7, 10)) {
|
||||
kError(1212) << "KWin requires at least Mesa 7.10 for OpenGL compositing.";
|
||||
return;
|
||||
|
@ -174,37 +171,18 @@ SceneOpenGL::SceneOpenGL(Workspace* ws)
|
|||
|
||||
debug = qstrcmp(qgetenv("KWIN_GL_DEBUG"), "1") == 0;
|
||||
|
||||
// scene shader setup
|
||||
if (GLPlatform::instance()->supports(GLSL)) {
|
||||
if (!ShaderManager::instance()->isValid()) {
|
||||
kDebug(1212) << "No Scene Shaders available";
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
// with OpenGL ES we need shaders, so let's break here
|
||||
return;
|
||||
#endif
|
||||
} else {
|
||||
// push one shader on the stack so that one is always bound
|
||||
ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
|
||||
}
|
||||
}
|
||||
|
||||
// OpenGL scene setup
|
||||
setupModelViewProjectionMatrix();
|
||||
if (checkGLError("Init")) {
|
||||
kError(1212) << "OpenGL compositing setup failed";
|
||||
return; // error
|
||||
}
|
||||
|
||||
// set strict binding
|
||||
if (options->isGlStrictBindingFollowsDriver()) {
|
||||
options->setGlStrictBinding(!glPlatform->supports(LooseBinding));
|
||||
}
|
||||
init_ok = true;
|
||||
}
|
||||
|
||||
SceneOpenGL::~SceneOpenGL()
|
||||
{
|
||||
delete m_backend;
|
||||
if (init_ok) {
|
||||
// backend might be still needed for a different scene
|
||||
delete m_backend;
|
||||
}
|
||||
foreach (Window * w, windows) {
|
||||
delete w;
|
||||
}
|
||||
|
@ -213,6 +191,45 @@ SceneOpenGL::~SceneOpenGL()
|
|||
checkGLError("Cleanup");
|
||||
}
|
||||
|
||||
SceneOpenGL *SceneOpenGL::createScene()
|
||||
{
|
||||
OpenGLBackend *backend = NULL;
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
backend = new EglOnXBackend();
|
||||
#else
|
||||
backend = new GlxBackend();
|
||||
#endif
|
||||
if (!backend || backend->isFailed()) {
|
||||
delete backend;
|
||||
return NULL;
|
||||
}
|
||||
SceneOpenGL *scene = NULL;
|
||||
// first let's try an OpenGL 2 scene
|
||||
if (SceneOpenGL2::supported(backend)) {
|
||||
scene = new SceneOpenGL2(backend);
|
||||
if (scene->initFailed()) {
|
||||
delete scene;
|
||||
scene = NULL;
|
||||
} else {
|
||||
return scene;
|
||||
}
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if (SceneOpenGL1::supported(backend)) {
|
||||
scene = new SceneOpenGL1(backend);
|
||||
if (scene->initFailed()) {
|
||||
delete scene;
|
||||
scene = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!scene) {
|
||||
delete backend;
|
||||
}
|
||||
|
||||
return scene;
|
||||
}
|
||||
|
||||
OverlayWindow *SceneOpenGL::overlayWindow()
|
||||
{
|
||||
return m_backend->overlayWindow();
|
||||
|
@ -244,10 +261,6 @@ int SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
|
|||
}
|
||||
|
||||
m_backend->prepareRenderingFrame();
|
||||
if (m_resetModelViewProjectionMatrix) {
|
||||
// reset model view projection matrix if required
|
||||
setupModelViewProjectionMatrix();
|
||||
}
|
||||
int mask = 0;
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError("Paint1");
|
||||
|
@ -265,30 +278,6 @@ int SceneOpenGL::paint(QRegion damage, ToplevelList toplevels)
|
|||
return m_backend->renderTime();
|
||||
}
|
||||
|
||||
void SceneOpenGL::setupModelViewProjectionMatrix()
|
||||
{
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float fovy = 60.0f;
|
||||
float aspect = 1.0f;
|
||||
float zNear = 0.1f;
|
||||
float zFar = 100.0f;
|
||||
float ymax = zNear * tan(fovy * M_PI / 360.0f);
|
||||
float ymin = -ymax;
|
||||
float xmin = ymin * aspect;
|
||||
float xmax = ymax * aspect;
|
||||
// swap top and bottom to have OpenGL coordinate system match X system
|
||||
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
float scaleFactor = 1.1 * tan(fovy * M_PI / 360.0f) / ymax;
|
||||
glTranslatef(xmin * scaleFactor, ymax * scaleFactor, -1.1);
|
||||
glScalef((xmax - xmin)*scaleFactor / displayWidth(), -(ymax - ymin)*scaleFactor / displayHeight(), 0.001);
|
||||
#endif
|
||||
m_resetModelViewProjectionMatrix = false;
|
||||
}
|
||||
|
||||
QMatrix4x4 SceneOpenGL::transformation(int mask, const ScreenPaintData &data) const
|
||||
{
|
||||
QMatrix4x4 matrix;
|
||||
|
@ -312,27 +301,6 @@ QMatrix4x4 SceneOpenGL::transformation(int mask, const ScreenPaintData &data) co
|
|||
return matrix;
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintGenericScreen(int mask, ScreenPaintData data)
|
||||
{
|
||||
ShaderManager *shaderManager = ShaderManager::instance();
|
||||
const bool useShader = shaderManager->isValid();
|
||||
const QMatrix4x4 matrix = transformation(mask, data);
|
||||
|
||||
if (useShader) {
|
||||
GLShader *shader = shaderManager->pushShader(ShaderManager::GenericShader);
|
||||
shader->setUniform(GLShader::ScreenTransformation, matrix);
|
||||
} else {
|
||||
pushMatrix(matrix);
|
||||
}
|
||||
|
||||
Scene::paintGenericScreen(mask, data);
|
||||
|
||||
if (useShader)
|
||||
shaderManager->popShader();
|
||||
else
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
void SceneOpenGL::paintBackground(QRegion region)
|
||||
{
|
||||
PaintClipper pc(region);
|
||||
|
@ -353,25 +321,13 @@ void SceneOpenGL::paintBackground(QRegion region)
|
|||
verts << r.x() + r.width() << r.y() + r.height();
|
||||
verts << r.x() + r.width() << r.y();
|
||||
}
|
||||
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
||||
vbo->reset();
|
||||
vbo->setUseColor(true);
|
||||
vbo->setData(verts.count() / 2, 2, verts.data(), NULL);
|
||||
const bool useShader = ShaderManager::instance()->isValid();
|
||||
if (useShader) {
|
||||
GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
|
||||
shader->setUniform(GLShader::Offset, QVector2D(0, 0));
|
||||
}
|
||||
vbo->render(GL_TRIANGLES);
|
||||
if (useShader) {
|
||||
ShaderManager::instance()->popShader();
|
||||
}
|
||||
doPaintBackground(verts);
|
||||
}
|
||||
|
||||
void SceneOpenGL::windowAdded(Toplevel* c)
|
||||
{
|
||||
assert(!windows.contains(c));
|
||||
Window *w = Window::createWindow(c);
|
||||
Window *w = createWindow(c);
|
||||
windows[ c ] = w;
|
||||
w->setScene(this);
|
||||
connect(c, SIGNAL(opacityChanged(KWin::Toplevel*,qreal)), SLOT(windowOpacityChanged(KWin::Toplevel*)));
|
||||
|
@ -444,11 +400,172 @@ void SceneOpenGL::screenGeometryChanged(const QSize &size)
|
|||
glViewport(0,0, size.width(), size.height());
|
||||
m_backend->screenGeometryChanged(size);
|
||||
ShaderManager::instance()->resetAllShaders();
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
m_resetModelViewProjectionMatrix = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// SceneOpenGL2
|
||||
//****************************************
|
||||
bool SceneOpenGL2::supported(OpenGLBackend *backend)
|
||||
{
|
||||
if (!backend->isDirectRendering()) {
|
||||
return false;
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
if (!GLPlatform::instance()->supports(GLSL) || GLPlatform::instance()->supports(LimitedNPOT)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
if (options->isGlLegacy()) {
|
||||
kDebug(1212) << "OpenGL 2 disabled by config option";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SceneOpenGL2::SceneOpenGL2(OpenGLBackend *backend)
|
||||
: SceneOpenGL(Workspace::self(), backend)
|
||||
{
|
||||
if (!ShaderManager::instance()->isValid()) {
|
||||
kDebug(1212) << "No Scene Shaders available";
|
||||
return;
|
||||
}
|
||||
|
||||
// push one shader on the stack so that one is always bound
|
||||
ShaderManager::instance()->pushShader(ShaderManager::SimpleShader);
|
||||
if (checkGLError("Init")) {
|
||||
kError(1212) << "OpenGL 2 compositing setup failed";
|
||||
return; // error
|
||||
}
|
||||
kDebug(1212) << "OpenGL 2 compositing successfully initialized";
|
||||
|
||||
init_ok = true;
|
||||
}
|
||||
|
||||
SceneOpenGL2::~SceneOpenGL2()
|
||||
{
|
||||
}
|
||||
|
||||
void SceneOpenGL2::paintGenericScreen(int mask, ScreenPaintData data)
|
||||
{
|
||||
ShaderManager *shaderManager = ShaderManager::instance();
|
||||
|
||||
GLShader *shader = shaderManager->pushShader(ShaderManager::GenericShader);
|
||||
shader->setUniform(GLShader::ScreenTransformation, transformation(mask, data));
|
||||
|
||||
Scene::paintGenericScreen(mask, data);
|
||||
|
||||
shaderManager->popShader();
|
||||
}
|
||||
|
||||
void SceneOpenGL2::doPaintBackground(const QVector< float >& vertices)
|
||||
{
|
||||
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
||||
vbo->reset();
|
||||
vbo->setUseColor(true);
|
||||
vbo->setData(vertices.count() / 2, 2, vertices.data(), NULL);
|
||||
|
||||
GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::ColorShader);
|
||||
shader->setUniform(GLShader::Offset, QVector2D(0, 0));
|
||||
|
||||
vbo->render(GL_TRIANGLES);
|
||||
|
||||
ShaderManager::instance()->popShader();
|
||||
}
|
||||
|
||||
SceneOpenGL::Window *SceneOpenGL2::createWindow(Toplevel *t)
|
||||
{
|
||||
return new SceneOpenGL2Window(t);
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// SceneOpenGL1
|
||||
//****************************************
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
bool SceneOpenGL1::supported(OpenGLBackend *backend)
|
||||
{
|
||||
// any OpenGL context will do
|
||||
return !backend->isFailed();
|
||||
}
|
||||
|
||||
SceneOpenGL1::SceneOpenGL1(OpenGLBackend *backend)
|
||||
: SceneOpenGL(Workspace::self(), backend)
|
||||
, m_resetModelViewProjectionMatrix(true)
|
||||
{
|
||||
ShaderManager::disable();
|
||||
setupModelViewProjectionMatrix();
|
||||
if (checkGLError("Init")) {
|
||||
kError(1212) << "OpenGL 1 compositing setup failed";
|
||||
return; // error
|
||||
}
|
||||
|
||||
kDebug(1212) << "OpenGL 1 compositing successfully initialized";
|
||||
init_ok = true;
|
||||
}
|
||||
|
||||
SceneOpenGL1::~SceneOpenGL1()
|
||||
{
|
||||
}
|
||||
|
||||
int SceneOpenGL1::paint(QRegion damage, ToplevelList windows)
|
||||
{
|
||||
if (m_resetModelViewProjectionMatrix) {
|
||||
// reset model view projection matrix if required
|
||||
setupModelViewProjectionMatrix();
|
||||
}
|
||||
return SceneOpenGL::paint(damage, windows);
|
||||
}
|
||||
|
||||
void SceneOpenGL1::paintGenericScreen(int mask, ScreenPaintData data)
|
||||
{
|
||||
pushMatrix(transformation(mask, data));
|
||||
Scene::paintGenericScreen(mask, data);
|
||||
popMatrix();
|
||||
}
|
||||
|
||||
void SceneOpenGL1::doPaintBackground(const QVector< float >& vertices)
|
||||
{
|
||||
GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer();
|
||||
vbo->reset();
|
||||
vbo->setUseColor(true);
|
||||
vbo->setData(vertices.count() / 2, 2, vertices.data(), NULL);
|
||||
vbo->render(GL_TRIANGLES);
|
||||
}
|
||||
|
||||
void SceneOpenGL1::setupModelViewProjectionMatrix()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
float fovy = 60.0f;
|
||||
float aspect = 1.0f;
|
||||
float zNear = 0.1f;
|
||||
float zFar = 100.0f;
|
||||
float ymax = zNear * tan(fovy * M_PI / 360.0f);
|
||||
float ymin = -ymax;
|
||||
float xmin = ymin * aspect;
|
||||
float xmax = ymax * aspect;
|
||||
// swap top and bottom to have OpenGL coordinate system match X system
|
||||
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
float scaleFactor = 1.1 * tan(fovy * M_PI / 360.0f) / ymax;
|
||||
glTranslatef(xmin * scaleFactor, ymax * scaleFactor, -1.1);
|
||||
glScalef((xmax - xmin)*scaleFactor / displayWidth(), -(ymax - ymin)*scaleFactor / displayHeight(), 0.001);
|
||||
m_resetModelViewProjectionMatrix = false;
|
||||
}
|
||||
|
||||
void SceneOpenGL1::screenGeometryChanged(const QSize &size)
|
||||
{
|
||||
SceneOpenGL::screenGeometryChanged(size);
|
||||
m_resetModelViewProjectionMatrix = true;
|
||||
}
|
||||
|
||||
SceneOpenGL::Window *SceneOpenGL1::createWindow(Toplevel *t)
|
||||
{
|
||||
return new SceneOpenGL1Window(t);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//****************************************
|
||||
// SceneOpenGL::Texture
|
||||
//****************************************
|
||||
|
@ -561,17 +678,6 @@ SceneOpenGL::Window::~Window()
|
|||
delete bottomTexture;
|
||||
}
|
||||
|
||||
SceneOpenGL::Window *SceneOpenGL::Window::createWindow(Toplevel *t)
|
||||
{
|
||||
if (ShaderManager::instance()->isValid()) {
|
||||
return new SceneOpenGL2Window(t);
|
||||
}
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
return new SceneOpenGL1Window(t);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Bind the window pixmap to an OpenGL texture.
|
||||
bool SceneOpenGL::Window::bindTexture()
|
||||
{
|
||||
|
|
|
@ -41,7 +41,6 @@ public:
|
|||
class Texture;
|
||||
class TexturePrivate;
|
||||
class Window;
|
||||
SceneOpenGL(Workspace* ws);
|
||||
virtual ~SceneOpenGL();
|
||||
virtual bool initFailed() const;
|
||||
virtual CompositingType compositingType() const {
|
||||
|
@ -65,23 +64,63 @@ public:
|
|||
Texture *createTexture();
|
||||
Texture *createTexture(const QPixmap& pix, GLenum target = GL_TEXTURE_2D);
|
||||
|
||||
static SceneOpenGL *createScene();
|
||||
|
||||
protected:
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
SceneOpenGL(Workspace* ws, OpenGLBackend *backend);
|
||||
virtual void paintBackground(QRegion region);
|
||||
QMatrix4x4 transformation(int mask, const ScreenPaintData &data) const;
|
||||
|
||||
virtual void doPaintBackground(const QVector<float> &vertices) = 0;
|
||||
virtual SceneOpenGL::Window *createWindow(Toplevel *t) = 0;
|
||||
public Q_SLOTS:
|
||||
virtual void windowOpacityChanged(KWin::Toplevel* c);
|
||||
virtual void windowGeometryShapeChanged(KWin::Toplevel* c);
|
||||
virtual void windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted);
|
||||
private:
|
||||
void setupModelViewProjectionMatrix();
|
||||
bool m_resetModelViewProjectionMatrix;
|
||||
QHash< Toplevel*, Window* > windows;
|
||||
protected:
|
||||
bool init_ok;
|
||||
private:
|
||||
QHash< Toplevel*, Window* > windows;
|
||||
bool debug;
|
||||
OpenGLBackend *m_backend;
|
||||
};
|
||||
|
||||
class SceneOpenGL2 : public SceneOpenGL
|
||||
{
|
||||
public:
|
||||
SceneOpenGL2(OpenGLBackend *backend);
|
||||
virtual ~SceneOpenGL2();
|
||||
|
||||
static bool supported(OpenGLBackend *backend);
|
||||
|
||||
protected:
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
virtual void doPaintBackground(const QVector< float >& vertices);
|
||||
virtual SceneOpenGL::Window *createWindow(Toplevel *t);
|
||||
};
|
||||
|
||||
#ifndef KWIN_HAVE_OPENGLES
|
||||
class SceneOpenGL1 : public SceneOpenGL
|
||||
{
|
||||
public:
|
||||
SceneOpenGL1(OpenGLBackend *backend);
|
||||
virtual ~SceneOpenGL1();
|
||||
virtual void screenGeometryChanged(const QSize &size);
|
||||
virtual int paint(QRegion damage, ToplevelList windows);
|
||||
|
||||
static bool supported(OpenGLBackend *backend);
|
||||
|
||||
protected:
|
||||
virtual void paintGenericScreen(int mask, ScreenPaintData data);
|
||||
virtual void doPaintBackground(const QVector< float >& vertices);
|
||||
virtual SceneOpenGL::Window *createWindow(Toplevel *t);
|
||||
|
||||
private:
|
||||
void setupModelViewProjectionMatrix();
|
||||
bool m_resetModelViewProjectionMatrix;
|
||||
};
|
||||
#endif
|
||||
|
||||
class SceneOpenGL::TexturePrivate
|
||||
: public GLTexturePrivate
|
||||
{
|
||||
|
@ -141,13 +180,6 @@ public:
|
|||
void setScene(SceneOpenGL *scene) {
|
||||
m_scene = scene;
|
||||
}
|
||||
/**
|
||||
* @brief Factory method to create a Window taking the OpenGL version into account.
|
||||
*
|
||||
* @param t The Toplevel for which a Scene Window should be created
|
||||
* @return :SceneOpenGL::Window* OpenGL version aware Window
|
||||
**/
|
||||
static SceneOpenGL::Window *createWindow(Toplevel *t);
|
||||
|
||||
protected:
|
||||
Window(Toplevel* c);
|
||||
|
|
Loading…
Reference in New Issue