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:
Martin Gräßlin 2011-01-30 11:55:27 +01:00
parent 1b70279664
commit 2f56415a21
7 changed files with 76 additions and 351 deletions

View file

@ -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() );
}

View file

@ -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>

View file

@ -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 );

View file

@ -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

View file

@ -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.

View file

@ -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;

View file

@ -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 );