Commit c1f1cfda authored by Martin Flöser's avatar Martin Flöser

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.
parent af9468aa
......@@ -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
{
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 );
}
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 );
}
else if( shm_mode )
{ // copy pixmap contents to a texture via shared memory
#ifdef HAVE_XSHM
GLenum pixfmt, type;
if( depth >= 24 )
// 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[] =
{
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 )
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()) )))
{
createTexture();
glBindTexture( mTarget, mTexture );
y_inverted = false;
glTexImage2D( mTarget, 0, depth == 32 ? GL_RGBA : GL_RGB,
mSize.width(), mSize.height(), 0,
pixfmt, type, NULL );
attrs[ 4 ] = GLX_TEXTURE_TARGET_EXT;
attrs[ 5 ] = GLX_TEXTURE_2D_EXT;
}
else
glBindTexture( mTarget, mTexture );
if( !region.isEmpty())
else if ( fbcdrawableinfo[ depth ].texture_targets & GLX_TEXTURE_RECTANGLE_BIT_EXT )
{
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 );
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( "TextureLoadSHM2" );
#endif
y_inverted = true;
can_use_mipmaps = true;
checkGLError( "TextureLoadTFP1" );
#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 );
y_inverted = fbcdrawableinfo[ depth ].y_inverted ? true : false;
can_use_mipmaps = fbcdrawableinfo[ depth ].mipmap ? true : false;
glBindTexture( mTarget, mTexture );
y_inverted = false;
can_use_mipmaps = true;
#ifdef CHECK_GL_ERROR
checkGLError( "TextureLoadTFP2" );
#endif
if( !options->glStrictBinding )
glXBindTexImageEXT( display(), glxpixmap, GLX_FRONT_LEFT_EXT, NULL );
}
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" );