Removing SHM and Fallback OpenGL Compositing modes.
Our primary target is Texture From Pixmap and it is supported by all important drivers nowadays. If a driver is not able to support TFP using OpenGL at all is probably no good idea and XRender is more suited.
This commit is contained in:
parent
1b70279664
commit
2f56415a21
7 changed files with 76 additions and 351 deletions
|
@ -127,7 +127,6 @@ KWinCompositingConfig::KWinCompositingConfig(QWidget *parent, const QVariantList
|
|||
connect(ui.glScaleFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
|
||||
connect(ui.xrScaleFilter, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
|
||||
|
||||
connect(ui.glMode, SIGNAL(currentIndexChanged(int)), this, SLOT(changed()));
|
||||
connect(ui.glDirect, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||
connect(ui.glVSync, SIGNAL(toggled(bool)), this, SLOT(changed()));
|
||||
connect(ui.compositingStateButton, SIGNAL(clicked(bool)), kwinInterface, SLOT(toggleCompositing()));
|
||||
|
@ -461,8 +460,6 @@ void KWinCompositingConfig::loadAdvancedTab()
|
|||
ui.xrScaleFilter->setCurrentIndex((int)config.readEntry("XRenderSmoothScale", false));
|
||||
ui.glScaleFilter->setCurrentIndex(config.readEntry("GLTextureFilter", 2));
|
||||
|
||||
QString glMode = config.readEntry("GLMode", "TFP");
|
||||
ui.glMode->setCurrentIndex((glMode == "TFP") ? 0 : ((glMode == "SHM") ? 1 : 2));
|
||||
ui.glDirect->setChecked(config.readEntry("GLDirect", mDefaultPrefs.enableDirectRendering()));
|
||||
ui.glVSync->setChecked(config.readEntry("GLVSync", mDefaultPrefs.enableVSync()));
|
||||
|
||||
|
@ -603,11 +600,9 @@ bool KWinCompositingConfig::saveAdvancedTab()
|
|||
static const int hps[] = { 6 /*always*/, 5 /*shown*/, 4 /*never*/ };
|
||||
|
||||
KConfigGroup config(mKWinConfig, "Compositing");
|
||||
QString glModes[] = { "TFP", "SHM", "Fallback" };
|
||||
|
||||
if( config.readEntry("Backend", "OpenGL")
|
||||
!= ((ui.compositingType->currentIndex() == 0) ? "OpenGL" : "XRender")
|
||||
|| config.readEntry("GLMode", "TFP") != glModes[ui.glMode->currentIndex()]
|
||||
|| config.readEntry("GLDirect", mDefaultPrefs.enableDirectRendering())
|
||||
!= ui.glDirect->isChecked()
|
||||
|| config.readEntry("GLVSync", mDefaultPrefs.enableVSync()) != ui.glVSync->isChecked()
|
||||
|
@ -629,7 +624,6 @@ bool KWinCompositingConfig::saveAdvancedTab()
|
|||
config.writeEntry("XRenderSmoothScale", ui.xrScaleFilter->currentIndex() == 1);
|
||||
config.writeEntry("GLTextureFilter", ui.glScaleFilter->currentIndex());
|
||||
|
||||
config.writeEntry("GLMode", glModes[ui.glMode->currentIndex()]);
|
||||
config.writeEntry("GLDirect", ui.glDirect->isChecked());
|
||||
config.writeEntry("GLVSync", ui.glVSync->isChecked());
|
||||
|
||||
|
@ -774,7 +768,6 @@ void KWinCompositingConfig::defaults()
|
|||
ui.unredirectFullscreen->setChecked( true );
|
||||
ui.xrScaleFilter->setCurrentIndex( 0 );
|
||||
ui.glScaleFilter->setCurrentIndex( 2 );
|
||||
ui.glMode->setCurrentIndex( 0 );
|
||||
ui.glDirect->setChecked( mDefaultPrefs.enableDirectRendering() );
|
||||
ui.glVSync->setChecked( mDefaultPrefs.enableVSync() );
|
||||
}
|
||||
|
|
|
@ -536,51 +536,7 @@ p, li { white-space: pre-wrap; }
|
|||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OpenGL mode:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>glMode</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="KComboBox" name="glMode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>3</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Texture From Pixmap</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Shared Memory</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Fallback</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="glDirect">
|
||||
<property name="text">
|
||||
<string>Enable direct rendering</string>
|
||||
|
@ -590,7 +546,7 @@ p, li { white-space: pre-wrap; }
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="glVSync">
|
||||
<property name="text">
|
||||
<string>Use VSync</string>
|
||||
|
|
|
@ -311,13 +311,6 @@ void Options::reloadCompositingSettings()
|
|||
else
|
||||
compositingMode = OpenGLCompositing;
|
||||
disableCompositingChecks = config.readEntry("DisableChecks", false);
|
||||
QString glmode = config.readEntry("GLMode", "TFP" ).toUpper();
|
||||
if( glmode == "TFP" )
|
||||
glMode = GLTFP;
|
||||
else if( glmode == "SHM" )
|
||||
glMode = GLSHM;
|
||||
else
|
||||
glMode = GLFallback;
|
||||
glDirect = config.readEntry("GLDirect", prefs.enableDirectRendering() );
|
||||
glVSync = config.readEntry("GLVSync", prefs.enableVSync() );
|
||||
glSmoothScale = qBound( -1, config.readEntry( "GLTextureFilter", 2 ), 2 );
|
||||
|
|
|
@ -347,8 +347,6 @@ class Options : public KDecorationOptions
|
|||
//----------------------
|
||||
// Compositing settings
|
||||
|
||||
enum GLMode { GLTFP, GLSHM, GLFallback };
|
||||
|
||||
CompositingType compositingMode;
|
||||
bool useCompositing; // Separate to mode so the user can toggle
|
||||
|
||||
|
@ -357,7 +355,6 @@ class Options : public KDecorationOptions
|
|||
bool unredirectFullscreen;
|
||||
bool disableCompositingChecks;
|
||||
// OpenGL
|
||||
GLMode glMode;
|
||||
int glSmoothScale; // 0 = no, 1 = yes when transformed,
|
||||
// 2 = try trilinear when transformed; else 1,
|
||||
// -1 = auto
|
||||
|
|
|
@ -77,8 +77,6 @@ Sources and other compositing managers:
|
|||
#include "deleted.h"
|
||||
#include "effects.h"
|
||||
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <math.h>
|
||||
|
||||
// turns on checks for opengl errors in various places (for easier finding of them)
|
||||
|
@ -103,12 +101,7 @@ extern int currentRefreshRate();
|
|||
// SceneOpenGL
|
||||
//****************************************
|
||||
|
||||
bool SceneOpenGL::tfp_mode; // using glXBindTexImageEXT (texture_from_pixmap)
|
||||
bool SceneOpenGL::db; // destination drawable is double-buffered
|
||||
bool SceneOpenGL::shm_mode;
|
||||
#ifdef HAVE_XSHM
|
||||
XShmSegmentInfo SceneOpenGL::shm;
|
||||
#endif
|
||||
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
#include "scene_opengl_egl.cpp"
|
||||
|
@ -123,80 +116,11 @@ bool SceneOpenGL::initFailed() const
|
|||
|
||||
bool SceneOpenGL::selectMode()
|
||||
{
|
||||
// select mode - try TFP first, then SHM, otherwise fallback mode
|
||||
shm_mode = false;
|
||||
tfp_mode = false;
|
||||
if( options->glMode == Options::GLTFP )
|
||||
{
|
||||
if( initTfp())
|
||||
tfp_mode = true;
|
||||
else if( initShm())
|
||||
shm_mode = true;
|
||||
}
|
||||
else if( options->glMode == Options::GLSHM )
|
||||
{
|
||||
if( initShm())
|
||||
shm_mode = true;
|
||||
else if( initTfp())
|
||||
tfp_mode = true;
|
||||
}
|
||||
if( !initDrawableConfigs())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SceneOpenGL::initShm()
|
||||
{
|
||||
#ifdef HAVE_XSHM
|
||||
int major, minor;
|
||||
Bool pixmaps;
|
||||
if( !XShmQueryVersion( display(), &major, &minor, &pixmaps ) || !pixmaps )
|
||||
return false;
|
||||
if( XShmPixmapFormat( display()) != ZPixmap )
|
||||
return false;
|
||||
const int MAXSIZE = 4096 * 2048 * 4; // TODO check there are not larger windows
|
||||
// TODO check that bytes_per_line doesn't involve padding?
|
||||
shm.readOnly = False;
|
||||
shm.shmid = shmget( IPC_PRIVATE, MAXSIZE, IPC_CREAT | 0600 );
|
||||
if( shm.shmid < 0 )
|
||||
return false;
|
||||
shm.shmaddr = ( char* ) shmat( shm.shmid, NULL, 0 );
|
||||
if( shm.shmaddr == ( void * ) -1 )
|
||||
{
|
||||
shmctl( shm.shmid, IPC_RMID, 0 );
|
||||
return false;
|
||||
}
|
||||
#ifdef __linux__
|
||||
// mark as deleted to automatically free the memory in case
|
||||
// of a crash (but this doesn't work e.g. on Solaris ... oh well)
|
||||
shmctl( shm.shmid, IPC_RMID, 0 );
|
||||
#endif
|
||||
KXErrorHandler errs;
|
||||
XShmAttach( display(), &shm );
|
||||
if( errs.error( true ))
|
||||
{
|
||||
#ifndef __linux__
|
||||
shmctl( shm.shmid, IPC_RMID, 0 );
|
||||
#endif
|
||||
shmdt( shm.shmaddr );
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SceneOpenGL::cleanupShm()
|
||||
{
|
||||
#ifdef HAVE_XSHM
|
||||
shmdt( shm.shmaddr );
|
||||
#ifndef __linux__
|
||||
shmctl( shm.shmid, IPC_RMID, 0 );
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// Test if compositing actually _really_ works, by creating a texture from a testing
|
||||
// window, drawing it on the screen, reading the contents back and comparing. This
|
||||
// should test whether compositing really works.
|
||||
|
|
|
@ -57,8 +57,6 @@ class SceneOpenGL
|
|||
private:
|
||||
bool selectMode();
|
||||
bool initTfp();
|
||||
bool initShm();
|
||||
void cleanupShm();
|
||||
bool initBuffer();
|
||||
bool initRenderingContext();
|
||||
bool initBufferConfigs();
|
||||
|
@ -94,12 +92,7 @@ class SceneOpenGL
|
|||
static GLXContext ctxdrawable;
|
||||
static GLXDrawable last_pixmap; // for a workaround in bindTexture()
|
||||
#endif
|
||||
static bool tfp_mode;
|
||||
static bool shm_mode;
|
||||
QHash< Toplevel*, Window* > windows;
|
||||
#ifdef HAVE_XSHM
|
||||
static XShmSegmentInfo shm;
|
||||
#endif
|
||||
bool init_ok;
|
||||
bool selfCheckDone;
|
||||
bool debug;
|
||||
|
|
|
@ -138,8 +138,7 @@ SceneOpenGL::SceneOpenGL( Workspace* ws )
|
|||
selfCheckDone = true;
|
||||
}
|
||||
#endif
|
||||
kDebug( 1212 ) << "DB:" << db << ", TFP:" << tfp_mode << ", SHM:" << shm_mode
|
||||
<< ", Direct:" << bool( glXIsDirect( display(), ctxbuffer )) << endl;
|
||||
kDebug( 1212 ) << "DB:" << db << ", Direct:" << bool( glXIsDirect( display(), ctxbuffer )) << endl;
|
||||
init_ok = true;
|
||||
}
|
||||
|
||||
|
@ -169,14 +168,6 @@ SceneOpenGL::~SceneOpenGL()
|
|||
XFreeGC( display(), gcroot );
|
||||
XFreePixmap( display(), buffer );
|
||||
}
|
||||
if( shm_mode )
|
||||
cleanupShm();
|
||||
if( !tfp_mode && !shm_mode )
|
||||
{
|
||||
if( last_pixmap != None )
|
||||
glXDestroyPixmap( display(), last_pixmap );
|
||||
glXDestroyContext( display(), ctxdrawable );
|
||||
}
|
||||
SceneOpenGL::EffectFrame::cleanup();
|
||||
checkGLError( "Cleanup" );
|
||||
}
|
||||
|
@ -191,8 +182,6 @@ bool SceneOpenGL::initTfp()
|
|||
bool SceneOpenGL::initRenderingContext()
|
||||
{
|
||||
bool direct_rendering = options->glDirect;
|
||||
if( !tfp_mode && !shm_mode )
|
||||
direct_rendering = false; // fallback doesn't seem to work with direct rendering
|
||||
KXErrorHandler errs1;
|
||||
ctxbuffer = glXCreateNewContext( display(), fbcbuffer, GLX_RGBA_TYPE, NULL,
|
||||
direct_rendering ? GL_TRUE : GL_FALSE );
|
||||
|
@ -223,11 +212,6 @@ bool SceneOpenGL::initRenderingContext()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if( !tfp_mode && !shm_mode )
|
||||
{
|
||||
ctxdrawable = glXCreateNewContext( display(), fbcdrawableinfo[ QX11Info::appDepth() ].fbconfig, GLX_RGBA_TYPE, ctxbuffer,
|
||||
direct_rendering ? GL_TRUE : GL_FALSE );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -414,30 +398,27 @@ bool SceneOpenGL::initDrawableConfigs()
|
|||
GLX_RENDER_TYPE, &value );
|
||||
if( !( value & GLX_RGBA_BIT ))
|
||||
continue;
|
||||
if( tfp_mode )
|
||||
value = 0;
|
||||
if( i == 32 )
|
||||
{
|
||||
value = 0;
|
||||
if( i == 32 )
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_BIND_TO_TEXTURE_RGBA_EXT, &value );
|
||||
if( value )
|
||||
{
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_BIND_TO_TEXTURE_RGBA_EXT, &value );
|
||||
if( value )
|
||||
{
|
||||
// TODO I think this should be set only after the config passes all tests
|
||||
rgba = 1;
|
||||
fbcdrawableinfo[ i ].bind_texture_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
|
||||
}
|
||||
// TODO I think this should be set only after the config passes all tests
|
||||
rgba = 1;
|
||||
fbcdrawableinfo[ i ].bind_texture_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
|
||||
}
|
||||
}
|
||||
if( !value )
|
||||
{
|
||||
if( rgba )
|
||||
continue;
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_BIND_TO_TEXTURE_RGB_EXT, &value );
|
||||
if( !value )
|
||||
{
|
||||
if( rgba )
|
||||
continue;
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_BIND_TO_TEXTURE_RGB_EXT, &value );
|
||||
if( !value )
|
||||
continue;
|
||||
fbcdrawableinfo[ i ].bind_texture_format = GLX_TEXTURE_FORMAT_RGB_EXT;
|
||||
}
|
||||
continue;
|
||||
fbcdrawableinfo[ i ].bind_texture_format = GLX_TEXTURE_FORMAT_RGB_EXT;
|
||||
}
|
||||
int back_value;
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
|
@ -455,7 +436,7 @@ bool SceneOpenGL::initDrawableConfigs()
|
|||
if( depth_value > depth )
|
||||
continue;
|
||||
int mipmap_value = -1;
|
||||
if( tfp_mode && GLTexture::framebufferObjectSupported())
|
||||
if( GLTexture::framebufferObjectSupported())
|
||||
{
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &mipmap_value );
|
||||
|
@ -474,12 +455,9 @@ bool SceneOpenGL::initDrawableConfigs()
|
|||
stencil = stencil_value;
|
||||
depth = depth_value;
|
||||
mipmap = mipmap_value;
|
||||
if ( tfp_mode )
|
||||
{
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value );
|
||||
fbcdrawableinfo[ i ].texture_targets = value;
|
||||
}
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value );
|
||||
fbcdrawableinfo[ i ].texture_targets = value;
|
||||
glXGetFBConfigAttrib( display(), fbconfigs[ j ],
|
||||
GLX_Y_INVERTED_EXT, &value );
|
||||
fbcdrawableinfo[ i ].y_inverted = value;
|
||||
|
@ -713,7 +691,7 @@ void SceneOpenGL::Texture::init()
|
|||
|
||||
void SceneOpenGL::Texture::release()
|
||||
{
|
||||
if( tfp_mode && glxpixmap != None )
|
||||
if( glxpixmap != None )
|
||||
{
|
||||
glXReleaseTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT );
|
||||
glXDestroyPixmap( display(), glxpixmap );
|
||||
|
@ -724,7 +702,7 @@ void SceneOpenGL::Texture::release()
|
|||
void SceneOpenGL::Texture::findTarget()
|
||||
{
|
||||
unsigned int new_target = 0;
|
||||
if( tfp_mode && glXQueryDrawable && glxpixmap != None )
|
||||
if( glXQueryDrawable && glxpixmap != None )
|
||||
glXQueryDrawable( display(), glxpixmap, GLX_TEXTURE_TARGET_EXT, &new_target );
|
||||
switch( new_target )
|
||||
{
|
||||
|
@ -751,14 +729,11 @@ bool SceneOpenGL::Texture::load( const Pixmap& pix, const QSize& size,
|
|||
#endif
|
||||
if( pix == None || size.isEmpty() || depth < 1 )
|
||||
return false;
|
||||
if( tfp_mode )
|
||||
if( fbcdrawableinfo[ depth ].fbconfig == NULL )
|
||||
{
|
||||
if( fbcdrawableinfo[ depth ].fbconfig == NULL )
|
||||
{
|
||||
kDebug( 1212 ) << "No framebuffer configuration for depth " << depth
|
||||
<< "; not binding pixmap" << endl;
|
||||
return false;
|
||||
}
|
||||
kDebug( 1212 ) << "No framebuffer configuration for depth " << depth
|
||||
<< "; not binding pixmap" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
mSize = size;
|
||||
|
@ -770,160 +745,54 @@ bool SceneOpenGL::Texture::load( const Pixmap& pix, const QSize& size,
|
|||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoad2" );
|
||||
#endif
|
||||
if( tfp_mode )
|
||||
{ // tfp mode, simply bind the pixmap to texture
|
||||
if( mTexture == None )
|
||||
createTexture();
|
||||
// The GLX pixmap references the contents of the original pixmap, so it doesn't
|
||||
// need to be recreated when the contents change.
|
||||
// The texture may or may not use the same storage depending on the EXT_tfp
|
||||
// implementation. When options->glStrictBinding is true, the texture uses
|
||||
// a different storage and needs to be updated with a call to
|
||||
// glXBindTexImageEXT() when the contents of the pixmap has changed.
|
||||
if( glxpixmap != None )
|
||||
glBindTexture( mTarget, mTexture );
|
||||
else
|
||||
// tfp mode, simply bind the pixmap to texture
|
||||
if( mTexture == None )
|
||||
createTexture();
|
||||
// The GLX pixmap references the contents of the original pixmap, so it doesn't
|
||||
// need to be recreated when the contents change.
|
||||
// The texture may or may not use the same storage depending on the EXT_tfp
|
||||
// implementation. When options->glStrictBinding is true, the texture uses
|
||||
// a different storage and needs to be updated with a call to
|
||||
// glXBindTexImageEXT() when the contents of the pixmap has changed.
|
||||
if( glxpixmap != None )
|
||||
glBindTexture( mTarget, mTexture );
|
||||
else
|
||||
{
|
||||
int attrs[] =
|
||||
{
|
||||
int attrs[] =
|
||||
{
|
||||
GLX_TEXTURE_FORMAT_EXT, fbcdrawableinfo[ depth ].bind_texture_format,
|
||||
GLX_MIPMAP_TEXTURE_EXT, fbcdrawableinfo[ depth ].mipmap,
|
||||
None, None, None
|
||||
};
|
||||
if ( ( fbcdrawableinfo[ depth ].texture_targets & GLX_TEXTURE_2D_BIT_EXT ) &&
|
||||
( GLTexture::NPOTTextureSupported() ||
|
||||
( isPowerOfTwo(size.width()) && isPowerOfTwo(size.height()) )))
|
||||
{
|
||||
attrs[ 4 ] = GLX_TEXTURE_TARGET_EXT;
|
||||
attrs[ 5 ] = GLX_TEXTURE_2D_EXT;
|
||||
}
|
||||
else if ( fbcdrawableinfo[ depth ].texture_targets & GLX_TEXTURE_RECTANGLE_BIT_EXT )
|
||||
{
|
||||
attrs[ 4 ] = GLX_TEXTURE_TARGET_EXT;
|
||||
attrs[ 5 ] = GLX_TEXTURE_RECTANGLE_EXT;
|
||||
}
|
||||
glxpixmap = glXCreatePixmap( display(), fbcdrawableinfo[ depth ].fbconfig, pix, attrs );
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoadTFP1" );
|
||||
#endif
|
||||
findTarget();
|
||||
y_inverted = fbcdrawableinfo[ depth ].y_inverted ? true : false;
|
||||
can_use_mipmaps = fbcdrawableinfo[ depth ].mipmap ? true : false;
|
||||
glBindTexture( mTarget, mTexture );
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoadTFP2" );
|
||||
#endif
|
||||
if( !options->glStrictBinding )
|
||||
glXBindTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
|
||||
GLX_TEXTURE_FORMAT_EXT, fbcdrawableinfo[ depth ].bind_texture_format,
|
||||
GLX_MIPMAP_TEXTURE_EXT, fbcdrawableinfo[ depth ].mipmap,
|
||||
None, None, None
|
||||
};
|
||||
if ( ( fbcdrawableinfo[ depth ].texture_targets & GLX_TEXTURE_2D_BIT_EXT ) &&
|
||||
( GLTexture::NPOTTextureSupported() ||
|
||||
( isPowerOfTwo(size.width()) && isPowerOfTwo(size.height()) )))
|
||||
{
|
||||
attrs[ 4 ] = GLX_TEXTURE_TARGET_EXT;
|
||||
attrs[ 5 ] = GLX_TEXTURE_2D_EXT;
|
||||
}
|
||||
if( options->glStrictBinding )
|
||||
// Mark the texture as damaged so it will be updated on the next call to bind()
|
||||
else if ( fbcdrawableinfo[ depth ].texture_targets & GLX_TEXTURE_RECTANGLE_BIT_EXT )
|
||||
{
|
||||
attrs[ 4 ] = GLX_TEXTURE_TARGET_EXT;
|
||||
attrs[ 5 ] = GLX_TEXTURE_RECTANGLE_EXT;
|
||||
}
|
||||
glxpixmap = glXCreatePixmap( display(), fbcdrawableinfo[ depth ].fbconfig, pix, attrs );
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoadTFP1" );
|
||||
#endif
|
||||
findTarget();
|
||||
y_inverted = fbcdrawableinfo[ depth ].y_inverted ? true : false;
|
||||
can_use_mipmaps = fbcdrawableinfo[ depth ].mipmap ? true : false;
|
||||
glBindTexture( mTarget, mTexture );
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoadTFP2" );
|
||||
#endif
|
||||
if( !options->glStrictBinding )
|
||||
glXBindTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
|
||||
}
|
||||
else if( shm_mode )
|
||||
{ // copy pixmap contents to a texture via shared memory
|
||||
#ifdef HAVE_XSHM
|
||||
GLenum pixfmt, type;
|
||||
if( depth >= 24 )
|
||||
{
|
||||
pixfmt = GL_BGRA;
|
||||
type = GL_UNSIGNED_BYTE;
|
||||
}
|
||||
else
|
||||
{ // depth 16
|
||||
pixfmt = GL_RGB;
|
||||
type = GL_UNSIGNED_SHORT_5_6_5;
|
||||
}
|
||||
findTarget();
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoadSHM1" );
|
||||
#endif
|
||||
if( mTexture == None )
|
||||
{
|
||||
createTexture();
|
||||
glBindTexture( mTarget, mTexture );
|
||||
y_inverted = false;
|
||||
glTexImage2D( mTarget, 0, depth == 32 ? GL_RGBA : GL_RGB,
|
||||
mSize.width(), mSize.height(), 0,
|
||||
pixfmt, type, NULL );
|
||||
}
|
||||
else
|
||||
glBindTexture( mTarget, mTexture );
|
||||
if( !region.isEmpty())
|
||||
{
|
||||
XGCValues xgcv;
|
||||
xgcv.graphics_exposures = False;
|
||||
xgcv.subwindow_mode = IncludeInferiors;
|
||||
GC gc = XCreateGC( display(), pix, GCGraphicsExposures | GCSubwindowMode, &xgcv );
|
||||
Pixmap p = XShmCreatePixmap( display(), rootWindow(), shm.shmaddr, &shm,
|
||||
mSize.width(), mSize.height(), depth );
|
||||
QRegion damage = optimizeBindDamage( region, 100 * 100 );
|
||||
glPixelStorei( GL_UNPACK_ROW_LENGTH, mSize.width());
|
||||
foreach( const QRect &r, damage.rects())
|
||||
{ // TODO for small areas it might be faster to not use SHM to avoid the XSync()
|
||||
XCopyArea( display(), pix, p, gc, r.x(), r.y(), r.width(), r.height(), 0, 0 );
|
||||
glXWaitX();
|
||||
glTexSubImage2D( mTarget, 0,
|
||||
r.x(), r.y(), r.width(), r.height(),
|
||||
pixfmt, type, shm.shmaddr );
|
||||
glXWaitGL();
|
||||
}
|
||||
glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 );
|
||||
XFreePixmap( display(), p );
|
||||
XFreeGC( display(), gc );
|
||||
}
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoadSHM2" );
|
||||
#endif
|
||||
y_inverted = true;
|
||||
can_use_mipmaps = true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{ // fallback, copy pixmap contents to a texture
|
||||
// note that if depth is not QX11Info::appDepth(), this may
|
||||
// not work (however, it does seem to work with nvidia)
|
||||
findTarget();
|
||||
GLXDrawable pixmap = glXCreatePixmap( display(), fbcdrawableinfo[ QX11Info::appDepth() ].fbconfig, pix, NULL );
|
||||
glXMakeCurrent( display(), pixmap, ctxdrawable );
|
||||
if( last_pixmap != None )
|
||||
glXDestroyPixmap( display(), last_pixmap );
|
||||
// workaround for ATI - it leaks/crashes when the pixmap is destroyed immediately
|
||||
// here (http://lists.kde.org/?l=kwin&m=116353772208535&w=2)
|
||||
last_pixmap = pixmap;
|
||||
glReadBuffer( GL_FRONT );
|
||||
glDrawBuffer( GL_FRONT );
|
||||
if( mTexture == None )
|
||||
{
|
||||
createTexture();
|
||||
glBindTexture( mTarget, mTexture );
|
||||
y_inverted = false;
|
||||
glCopyTexImage2D( mTarget, 0,
|
||||
depth == 32 ? GL_RGBA : GL_RGB,
|
||||
0, 0, mSize.width(), mSize.height(), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindTexture( mTarget, mTexture );
|
||||
QRegion damage = optimizeBindDamage( region, 30 * 30 );
|
||||
foreach( const QRect &r, damage.rects())
|
||||
{
|
||||
// convert to OpenGL coordinates (this is mapping
|
||||
// the pixmap to a texture, this is not affected
|
||||
// by using glOrtho() for the OpenGL scene)
|
||||
int gly = mSize.height() - r.y() - r.height();
|
||||
glCopyTexSubImage2D( mTarget, 0,
|
||||
r.x(), gly, r.x(), gly, r.width(), r.height());
|
||||
}
|
||||
}
|
||||
glXWaitGL();
|
||||
if( db )
|
||||
glDrawBuffer( GL_BACK );
|
||||
glXMakeCurrent( display(), glxbuffer, ctxbuffer );
|
||||
glBindTexture( mTarget, mTexture );
|
||||
y_inverted = false;
|
||||
can_use_mipmaps = true;
|
||||
}
|
||||
if( options->glStrictBinding )
|
||||
// Mark the texture as damaged so it will be updated on the next call to bind()
|
||||
glXBindTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
|
||||
#ifdef CHECK_GL_ERROR
|
||||
checkGLError( "TextureLoad0" );
|
||||
#endif
|
||||
|
@ -934,7 +803,7 @@ void SceneOpenGL::Texture::bind()
|
|||
{
|
||||
glEnable( mTarget );
|
||||
glBindTexture( mTarget, mTexture );
|
||||
if( tfp_mode && options->glStrictBinding )
|
||||
if( options->glStrictBinding )
|
||||
{
|
||||
assert( glxpixmap != None );
|
||||
glXReleaseTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT );
|
||||
|
@ -955,7 +824,7 @@ void SceneOpenGL::Texture::unbind()
|
|||
{
|
||||
glTexEnvf( GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.0f );
|
||||
}
|
||||
if( tfp_mode && options->glStrictBinding )
|
||||
if( options->glStrictBinding )
|
||||
{
|
||||
assert( glxpixmap != None );
|
||||
glBindTexture( mTarget, mTexture );
|
||||
|
|
Loading…
Reference in a new issue