Abstract paint clipping into PaintClipper helper class that allows
stacking of clipping regions. (http://lists.kde.org/?l=kwin&m=120138051215450&w=2) BUG: 156798 svn path=/trunk/KDE/kdebase/workspace/; revision=779045
This commit is contained in:
parent
73ad1f1adc
commit
cff2b0e6cd
19 changed files with 347 additions and 162 deletions
|
@ -261,7 +261,7 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
||||||
frameRect.y() + frameRect.height()*0.1f,
|
frameRect.y() + frameRect.height()*0.1f,
|
||||||
frameRect.height()*0.8f,
|
frameRect.height()*0.8f,
|
||||||
frameRect.height()*0.8f );
|
frameRect.height()*0.8f );
|
||||||
icon->render( false, region, iconRect);
|
icon->render( region, iconRect);
|
||||||
icon->unbind();
|
icon->unbind();
|
||||||
glDisable( GL_BLEND );
|
glDisable( GL_BLEND );
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
|
|
|
@ -146,11 +146,19 @@ void DesktopGridEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
|
||||||
++desktop )
|
++desktop )
|
||||||
{
|
{
|
||||||
if( desktop != desktop_with_move )
|
if( desktop != desktop_with_move )
|
||||||
|
{
|
||||||
|
PaintClipper pc( desktopRect( desktop, true ));
|
||||||
paintScreenDesktop( desktop, mask, region, data );
|
paintScreenDesktop( desktop, mask, region, data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// paint the desktop with the window being moved as the last one, i.e. on top of others
|
// paint the desktop with the window being moved as the last one, i.e. on top of others
|
||||||
if( desktop_with_move != -1 )
|
if( desktop_with_move != -1 )
|
||||||
|
{
|
||||||
|
QRegion paintreg = desktopRect( desktop_with_move, true ); // paint only the desktop
|
||||||
|
paintreg |= windowRect( window_move ); // and wherever the moved window is
|
||||||
|
PaintClipper pc( paintreg );
|
||||||
paintScreenDesktop( desktop_with_move, mask, region, data );
|
paintScreenDesktop( desktop_with_move, mask, region, data );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesktopGridEffect::paintScreenDesktop( int desktop, int mask, QRegion region, ScreenPaintData data )
|
void DesktopGridEffect::paintScreenDesktop( int desktop, int mask, QRegion region, ScreenPaintData data )
|
||||||
|
|
|
@ -363,7 +363,7 @@ void FlipSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& d
|
||||||
frameRect.y() + frameRect.height()*0.1f,
|
frameRect.y() + frameRect.height()*0.1f,
|
||||||
frameRect.height()*0.8f,
|
frameRect.height()*0.8f,
|
||||||
frameRect.height()*0.8f );
|
frameRect.height()*0.8f );
|
||||||
icon->render( false, region, iconRect);
|
icon->render( region, iconRect);
|
||||||
icon->unbind();
|
icon->unbind();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -81,13 +81,8 @@ void MagnifierEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da
|
||||||
effects->paintScreen( mask, region, data ); // paint normal screen
|
effects->paintScreen( mask, region, data ); // paint normal screen
|
||||||
if( zoom != 1.0 )
|
if( zoom != 1.0 )
|
||||||
{ // paint magnifier
|
{ // paint magnifier
|
||||||
// ## TODO this should be inside KWIN_HAVE_OPENGL_COMPOSITING
|
|
||||||
glPushAttrib( GL_ENABLE_BIT );
|
|
||||||
QRect area = magnifierArea();
|
QRect area = magnifierArea();
|
||||||
glEnable( GL_SCISSOR_TEST );
|
PaintClipper::push( area ); // don't allow any painting outside of the area
|
||||||
int dh = displayHeight();
|
|
||||||
// Scissor rect has to be given in OpenGL coords
|
|
||||||
glScissor( area.x(), dh - area.y() - area.height(), area.width(), area.height());
|
|
||||||
mask |= PAINT_SCREEN_TRANSFORMED;
|
mask |= PAINT_SCREEN_TRANSFORMED;
|
||||||
data2.xScale *= zoom;
|
data2.xScale *= zoom;
|
||||||
data2.yScale *= zoom;
|
data2.yScale *= zoom;
|
||||||
|
@ -96,27 +91,33 @@ void MagnifierEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da
|
||||||
data2.xTranslate = - int( cursor.x() * ( zoom - 1 ));
|
data2.xTranslate = - int( cursor.x() * ( zoom - 1 ));
|
||||||
data2.yTranslate = - int( cursor.y() * ( zoom - 1 ));
|
data2.yTranslate = - int( cursor.y() * ( zoom - 1 ));
|
||||||
effects->paintScreen( mask, region, data2 );
|
effects->paintScreen( mask, region, data2 );
|
||||||
glPopAttrib();
|
PaintClipper::pop( area );
|
||||||
|
// ## TODO this should be inside KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
glPushAttrib( GL_CURRENT_BIT );
|
glPushAttrib( GL_CURRENT_BIT );
|
||||||
glColor4f( 0, 0, 0, 1 ); // black
|
glColor4f( 0, 0, 0, 1 ); // black
|
||||||
glBegin( GL_QUADS );
|
for( PaintClipper::Iterator iterator;
|
||||||
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // top frame
|
!iterator.isDone();
|
||||||
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
|
iterator.next())
|
||||||
glVertex2i( area.right() + FRAME_WIDTH, area.top() - 1 );
|
{
|
||||||
glVertex2i( area.left() - FRAME_WIDTH, area.top() - 1 );
|
glBegin( GL_QUADS );
|
||||||
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // left frame
|
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // top frame
|
||||||
glVertex2i( area.left() - 1, area.top() - FRAME_WIDTH );
|
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
|
||||||
glVertex2i( area.left() - 1, area.bottom() + FRAME_WIDTH );
|
glVertex2i( area.right() + FRAME_WIDTH, area.top() - 1 );
|
||||||
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
glVertex2i( area.left() - FRAME_WIDTH, area.top() - 1 );
|
||||||
glVertex2i( area.right() + 1, area.top() - FRAME_WIDTH ); // right frame
|
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // left frame
|
||||||
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
|
glVertex2i( area.left() - 1, area.top() - FRAME_WIDTH );
|
||||||
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
glVertex2i( area.left() - 1, area.bottom() + FRAME_WIDTH );
|
||||||
glVertex2i( area.right() + 1, area.bottom() + FRAME_WIDTH );
|
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
||||||
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + 1 ); // bottom frame
|
glVertex2i( area.right() + 1, area.top() - FRAME_WIDTH ); // right frame
|
||||||
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + 1 );
|
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
|
||||||
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
||||||
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
glVertex2i( area.right() + 1, area.bottom() + FRAME_WIDTH );
|
||||||
glEnd();
|
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + 1 ); // bottom frame
|
||||||
|
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + 1 );
|
||||||
|
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
||||||
|
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,7 @@ void PresentWindowsEffect::paintScreen( int mask, QRegion region, ScreenPaintDat
|
||||||
renderRoundBoxWithEdge( filterFrameRect );
|
renderRoundBoxWithEdge( filterFrameRect );
|
||||||
// And then the text on top of it
|
// And then the text on top of it
|
||||||
filterTexture->bind();
|
filterTexture->bind();
|
||||||
filterTexture->render( mask, region, filterTextureRect );
|
filterTexture->render( region, filterTextureRect );
|
||||||
filterTexture->unbind();
|
filterTexture->unbind();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ void ShadowEffect::drawWindow( EffectWindow* w, int mask, QRegion region, Window
|
||||||
{
|
{
|
||||||
// For translucent windows, shadow needs to be drawn before the
|
// For translucent windows, shadow needs to be drawn before the
|
||||||
// window itself.
|
// window itself.
|
||||||
drawShadow( w, mask, region, data, false );
|
drawShadow( w, mask, region, data );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -145,7 +145,7 @@ void ShadowEffect::drawQueuedShadows( EffectWindow* behindWindow )
|
||||||
// that are behind that window.
|
// that are behind that window.
|
||||||
if( !behindWindow || stack.indexOf(d.w) < stack.indexOf(behindWindow))
|
if( !behindWindow || stack.indexOf(d.w) < stack.indexOf(behindWindow))
|
||||||
{
|
{
|
||||||
drawShadow( d.w, d.mask, d.region.subtracted( d.clip ), d.data, true );
|
drawShadow( d.w, d.mask, d.region.subtracted( d.clip ), d.data );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -155,7 +155,7 @@ void ShadowEffect::drawQueuedShadows( EffectWindow* behindWindow )
|
||||||
shadowDatas = newShadowDatas;
|
shadowDatas = newShadowDatas;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShadowEffect::drawShadow( EffectWindow* window, int mask, QRegion region, WindowPaintData& data, bool clip )
|
void ShadowEffect::drawShadow( EffectWindow* window, int mask, QRegion region, WindowPaintData& data )
|
||||||
{
|
{
|
||||||
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT );
|
glPushAttrib( GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT );
|
||||||
glEnable( GL_BLEND );
|
glEnable( GL_BLEND );
|
||||||
|
@ -219,10 +219,7 @@ void ShadowEffect::drawShadow( EffectWindow* window, int mask, QRegion region, W
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
// We have two elements per vertex in the verts array
|
// We have two elements per vertex in the verts array
|
||||||
int verticesCount = verts.count() / 2;
|
int verticesCount = verts.count() / 2;
|
||||||
if( clip )
|
renderGLGeometry( region, verticesCount, verts.data(), texcoords.data() );
|
||||||
renderGLGeometry( true, region, verticesCount, verts.data(), texcoords.data() );
|
|
||||||
else
|
|
||||||
renderGLGeometry( mask, region, verticesCount, verts.data(), texcoords.data() );
|
|
||||||
mShadowTexture->unbind();
|
mShadowTexture->unbind();
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
|
@ -40,7 +40,7 @@ class ShadowEffect
|
||||||
virtual void windowClosed( EffectWindow* c );
|
virtual void windowClosed( EffectWindow* c );
|
||||||
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
|
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
|
||||||
private:
|
private:
|
||||||
void drawShadow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data, bool clip );
|
void drawShadow( EffectWindow* w, int mask, QRegion region, WindowPaintData& data );
|
||||||
void addQuadVertices(QVector<float>& verts, float x1, float y1, float x2, float y2) const;
|
void addQuadVertices(QVector<float>& verts, float x1, float y1, float x2, float y2) const;
|
||||||
// transforms window rect -> shadow rect
|
// transforms window rect -> shadow rect
|
||||||
QRect shadowRectangle(const QRect& windowRectangle) const;
|
QRect shadowRectangle(const QRect& windowRectangle) const;
|
||||||
|
|
|
@ -439,7 +439,7 @@ void ShowFpsEffect::paintFPSText(int fps)
|
||||||
delete fpsText;
|
delete fpsText;
|
||||||
fpsText = new GLTexture(im);
|
fpsText = new GLTexture(im);
|
||||||
fpsText->bind();
|
fpsText->bind();
|
||||||
fpsText->render(false, QRegion(fpsTextRect), fpsTextRect);
|
fpsText->render(QRegion(fpsTextRect), fpsTextRect);
|
||||||
fpsText->unbind();
|
fpsText->unbind();
|
||||||
effects->addRepaint(fpsTextRect);
|
effects->addRepaint(fpsTextRect);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -142,7 +142,7 @@ void SnowEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
|
||||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
for (int i=0; i<flakes->count(); i++)
|
for (int i=0; i<flakes->count(); i++)
|
||||||
{
|
{
|
||||||
texture->render( false, region, flakes->at(i));
|
texture->render( region, flakes->at(i));
|
||||||
}
|
}
|
||||||
texture->unbind();
|
texture->unbind();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
|
|
|
@ -77,7 +77,7 @@ void TrackMouseEffect::paintScreen( int mask, QRegion region, ScreenPaintData& d
|
||||||
++i )
|
++i )
|
||||||
{
|
{
|
||||||
QRect r = starRect( i );
|
QRect r = starRect( i );
|
||||||
texture->render( mask, region, r );
|
texture->render( region, r );
|
||||||
}
|
}
|
||||||
texture->unbind();
|
texture->unbind();
|
||||||
glPopAttrib();
|
glPopAttrib();
|
||||||
|
|
|
@ -677,4 +677,168 @@ bool WindowQuadList::smoothNeeded() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
PaintClipper
|
||||||
|
***************************************************************/
|
||||||
|
|
||||||
|
QStack< QRegion >* PaintClipper::areas = NULL;
|
||||||
|
|
||||||
|
PaintClipper::PaintClipper( const QRegion& allowed_area )
|
||||||
|
: area( allowed_area )
|
||||||
|
{
|
||||||
|
push( area );
|
||||||
|
}
|
||||||
|
|
||||||
|
PaintClipper::~PaintClipper()
|
||||||
|
{
|
||||||
|
pop( area );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaintClipper::push( const QRegion& allowed_area )
|
||||||
|
{
|
||||||
|
if( allowed_area == infiniteRegion()) // don't push these
|
||||||
|
return;
|
||||||
|
if( areas == NULL )
|
||||||
|
areas = new QStack< QRegion >;
|
||||||
|
areas->push( allowed_area );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaintClipper::pop( const QRegion& allowed_area )
|
||||||
|
{
|
||||||
|
if( allowed_area == infiniteRegion())
|
||||||
|
return;
|
||||||
|
Q_ASSERT( areas != NULL );
|
||||||
|
Q_ASSERT( areas->top() == allowed_area );
|
||||||
|
areas->pop();
|
||||||
|
if( areas->isEmpty())
|
||||||
|
{
|
||||||
|
delete areas;
|
||||||
|
areas = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PaintClipper::clip()
|
||||||
|
{
|
||||||
|
return areas != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegion PaintClipper::paintArea()
|
||||||
|
{
|
||||||
|
QRegion ret = QRegion( 0, 0, displayWidth(), displayHeight());
|
||||||
|
foreach( QRegion r, *areas )
|
||||||
|
ret &= r;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PaintClipper::Iterator::Data
|
||||||
|
{
|
||||||
|
Data() : index( 0 ) {}
|
||||||
|
int index;
|
||||||
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
QVector< QRect > rects;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
PaintClipper::Iterator::Iterator()
|
||||||
|
: data( new Data )
|
||||||
|
{
|
||||||
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
if( clip() && effects->compositingType() == OpenGLCompositing )
|
||||||
|
{
|
||||||
|
glPushAttrib( GL_SCISSOR_BIT );
|
||||||
|
glEnable( GL_SCISSOR_TEST );
|
||||||
|
data->rects = paintArea().rects();
|
||||||
|
data->index = -1;
|
||||||
|
next(); // move to the first one
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
|
if( clip() && effects->compositingType() == XRenderCompositing )
|
||||||
|
{
|
||||||
|
XserverRegion region = toXserverRegion( paintArea());
|
||||||
|
XFixesSetPictureClipRegion( display(), effects->xrenderBufferPicture(), 0, 0, region );
|
||||||
|
XFixesDestroyRegion( display(), region ); // it's ref-counted
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
PaintClipper::Iterator::~Iterator()
|
||||||
|
{
|
||||||
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
if( clip() && effects->compositingType() == OpenGLCompositing )
|
||||||
|
glPopAttrib();
|
||||||
|
#endif
|
||||||
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
|
if( clip() && effects->compositingType() == XRenderCompositing )
|
||||||
|
XFixesSetPictureClipRegion( display(), effects->xrenderBufferPicture(), 0, 0, None );
|
||||||
|
#endif
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PaintClipper::Iterator::isDone()
|
||||||
|
{
|
||||||
|
if( !clip())
|
||||||
|
return data->index == 1; // run once
|
||||||
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
if( effects->compositingType() == OpenGLCompositing )
|
||||||
|
return data->index >= data->rects.count(); // run once per each area
|
||||||
|
#endif
|
||||||
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
|
if( effects->compositingType() == XRenderCompositing )
|
||||||
|
return data->index == 1; // run once
|
||||||
|
#endif
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
void PaintClipper::Iterator::next()
|
||||||
|
{
|
||||||
|
data->index++;
|
||||||
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
if( clip() && effects->compositingType() == OpenGLCompositing && data->index < data->rects.count())
|
||||||
|
{
|
||||||
|
const QRect& r = data->rects[ data->index ];
|
||||||
|
// Scissor rect has to be given in OpenGL coords
|
||||||
|
glScissor( r.x(), displayHeight() - r.y() - r.height(), r.width(), r.height());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect PaintClipper::Iterator::boundingRect() const
|
||||||
|
{
|
||||||
|
if( !clip())
|
||||||
|
return infiniteRegion();
|
||||||
|
#ifdef KWIN_HAVE_OPENGL_COMPOSITING
|
||||||
|
if( effects->compositingType() == OpenGLCompositing )
|
||||||
|
return data->rects[ data->index ];
|
||||||
|
#endif
|
||||||
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
|
if( effects->compositingType() == XRenderCompositing )
|
||||||
|
return paintArea().boundingRect();
|
||||||
|
#endif
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Convert QRegion to XserverRegion. All code uses XserverRegion
|
||||||
|
// only when really necessary as the shared implementation uses
|
||||||
|
// QRegion.
|
||||||
|
XserverRegion toXserverRegion( QRegion region )
|
||||||
|
{
|
||||||
|
QVector< QRect > rects = region.rects();
|
||||||
|
XRectangle* xr = new XRectangle[ rects.count() ];
|
||||||
|
for( int i = 0;
|
||||||
|
i < rects.count();
|
||||||
|
++i )
|
||||||
|
{
|
||||||
|
xr[ i ].x = rects[ i ].x();
|
||||||
|
xr[ i ].y = rects[ i ].y();
|
||||||
|
xr[ i ].width = rects[ i ].width();
|
||||||
|
xr[ i ].height = rects[ i ].height();
|
||||||
|
}
|
||||||
|
XserverRegion ret = XFixesCreateRegion( display(), xr, rects.count());
|
||||||
|
delete[] xr;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -32,12 +32,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <QtCore/QVector>
|
#include <QtCore/QVector>
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QHash>
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QStack>
|
||||||
|
|
||||||
#include <KDE/KPluginFactory>
|
#include <KDE/KPluginFactory>
|
||||||
#include <KDE/KShortcutsEditor>
|
#include <KDE/KShortcutsEditor>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
|
#include <X11/extensions/Xfixes.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
class KLibrary;
|
class KLibrary;
|
||||||
class KConfigGroup;
|
class KConfigGroup;
|
||||||
|
@ -160,10 +165,26 @@ X-KDE-Library=kwin4_effect_cooleffect
|
||||||
|
|
||||||
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
|
#define KWIN_EFFECT_API_MAKE_VERSION( major, minor ) (( major ) << 8 | ( minor ))
|
||||||
#define KWIN_EFFECT_API_VERSION_MAJOR 0
|
#define KWIN_EFFECT_API_VERSION_MAJOR 0
|
||||||
#define KWIN_EFFECT_API_VERSION_MINOR 6
|
#define KWIN_EFFECT_API_VERSION_MINOR 7
|
||||||
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
|
#define KWIN_EFFECT_API_VERSION KWIN_EFFECT_API_MAKE_VERSION( \
|
||||||
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
|
KWIN_EFFECT_API_VERSION_MAJOR, KWIN_EFFECT_API_VERSION_MINOR )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infinite region (i.e. a special region type saying that everything needs to be painted).
|
||||||
|
*/
|
||||||
|
KWIN_EXPORT inline
|
||||||
|
QRect infiniteRegion()
|
||||||
|
{ // INT_MIN / 2 because width/height is used (INT_MIN+INT_MAX==-1)
|
||||||
|
return QRect( INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX );
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
|
||||||
|
/**
|
||||||
|
* Convert QRegion to XserverRegion.
|
||||||
|
*/
|
||||||
|
KWIN_EXPORT XserverRegion toXserverRegion( QRegion region );
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @short Base class for all KWin effects
|
* @short Base class for all KWin effects
|
||||||
*
|
*
|
||||||
|
@ -822,6 +843,71 @@ class KWIN_EXPORT ScreenPrePaintData
|
||||||
QRegion paint;
|
QRegion paint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @short Helper class for restricting painting area only to allowed area.
|
||||||
|
*
|
||||||
|
* This helper class helps specifying areas that should be painted, clipping
|
||||||
|
* out the rest. The simplest usage is creating an object on the stack
|
||||||
|
* and giving it the area that is allowed to be painted to. When the object
|
||||||
|
* is destroyed, the restriction will be removed.
|
||||||
|
* Note that all painting code must use paintArea() to actually perform the clipping.
|
||||||
|
*/
|
||||||
|
class KWIN_EXPORT PaintClipper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Calls push().
|
||||||
|
*/
|
||||||
|
PaintClipper( const QRegion& allowed_area );
|
||||||
|
/**
|
||||||
|
* Calls pop().
|
||||||
|
*/
|
||||||
|
~PaintClipper();
|
||||||
|
/**
|
||||||
|
* Allows painting only in the given area. When areas have been already
|
||||||
|
* specified, painting is allowed only in the intersection of all areas.
|
||||||
|
*/
|
||||||
|
static void push( const QRegion& allowed_area );
|
||||||
|
/**
|
||||||
|
* Removes the given area. It must match the top item in the stack.
|
||||||
|
*/
|
||||||
|
static void pop( const QRegion& allowed_area );
|
||||||
|
/**
|
||||||
|
* Returns true if any clipping should be performed.
|
||||||
|
*/
|
||||||
|
static bool clip();
|
||||||
|
/**
|
||||||
|
* If clip() returns true, this function gives the resulting area in which
|
||||||
|
* painting is allowed. It is usually simpler to use the helper Iterator class.
|
||||||
|
*/
|
||||||
|
static QRegion paintArea();
|
||||||
|
/**
|
||||||
|
* Helper class to perform the clipped painting. The usage is:
|
||||||
|
* @code
|
||||||
|
* for( PaintClipper::Iterator iterator;
|
||||||
|
* !iterator.isDone();
|
||||||
|
* iterator.next())
|
||||||
|
* { // do the painting, possibly use iterator.boundingRect()
|
||||||
|
* }
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
class Iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Iterator();
|
||||||
|
~Iterator();
|
||||||
|
bool isDone();
|
||||||
|
void next();
|
||||||
|
QRect boundingRect() const;
|
||||||
|
private:
|
||||||
|
struct Data;
|
||||||
|
Data* data;
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
QRegion area;
|
||||||
|
static QStack< QRegion >* areas;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to the global EffectsHandler object.
|
* Pointer to the global EffectsHandler object.
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -128,18 +128,10 @@ int nearestPowerOfTwo( int x )
|
||||||
void renderGLGeometry( int count, const float* vertices, const float* texture, const float* color,
|
void renderGLGeometry( int count, const float* vertices, const float* texture, const float* color,
|
||||||
int dim, int stride )
|
int dim, int stride )
|
||||||
{
|
{
|
||||||
return renderGLGeometry( false, QRegion(), count, vertices, texture, color, dim, stride );
|
return renderGLGeometry( infiniteRegion(), count, vertices, texture, color, dim, stride );
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderGLGeometry( int mask, const QRegion& region, int count,
|
void renderGLGeometry( const QRegion& region, int count,
|
||||||
const float* vertices, const float* texture, const float* color,
|
|
||||||
int dim, int stride )
|
|
||||||
{
|
|
||||||
return renderGLGeometry( !( mask & ( Effect::PAINT_WINDOW_TRANSFORMED | Effect::PAINT_SCREEN_TRANSFORMED )),
|
|
||||||
region, count, vertices, texture, color, dim, stride );
|
|
||||||
}
|
|
||||||
|
|
||||||
void renderGLGeometry( bool clip, const QRegion& region, int count,
|
|
||||||
const float* vertices, const float* texture, const float* color,
|
const float* vertices, const float* texture, const float* color,
|
||||||
int dim, int stride )
|
int dim, int stride )
|
||||||
{
|
{
|
||||||
|
@ -166,40 +158,17 @@ void renderGLGeometry( bool clip, const QRegion& region, int count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render
|
// Clip using scissoring
|
||||||
if( !clip )
|
PaintClipper pc( region );
|
||||||
|
for( PaintClipper::Iterator iterator;
|
||||||
|
!iterator.isDone();
|
||||||
|
iterator.next())
|
||||||
{
|
{
|
||||||
// Just draw the entire window, no clipping
|
|
||||||
if( use_arrays )
|
if( use_arrays )
|
||||||
glDrawArrays( GL_QUADS, 0, count );
|
glDrawArrays( GL_QUADS, 0, count );
|
||||||
else
|
else
|
||||||
renderGLGeometryImmediate( count, vertices, texture, color, dim, stride );
|
renderGLGeometryImmediate( count, vertices, texture, color, dim, stride );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// Make sure there's only a single quad (no transformed vertices)
|
|
||||||
// Clip using scissoring
|
|
||||||
glEnable( GL_SCISSOR_TEST );
|
|
||||||
int dh = displayHeight();
|
|
||||||
if( use_arrays )
|
|
||||||
{
|
|
||||||
foreach( QRect r, region.rects())
|
|
||||||
{
|
|
||||||
// Scissor rect has to be given in OpenGL coords
|
|
||||||
glScissor(r.x(), dh - r.y() - r.height(), r.width(), r.height());
|
|
||||||
glDrawArrays( GL_QUADS, 0, count );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach( QRect r, region.rects())
|
|
||||||
{
|
|
||||||
// Scissor rect has to be given in OpenGL coords
|
|
||||||
glScissor(r.x(), dh - r.y() - r.height(), r.width(), r.height());
|
|
||||||
renderGLGeometryImmediate( count, vertices, texture, color, dim, stride );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( use_arrays )
|
if( use_arrays )
|
||||||
{
|
{
|
||||||
|
@ -500,13 +469,7 @@ void GLTexture::unbind()
|
||||||
glDisable( mTarget );
|
glDisable( mTarget );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLTexture::render( int mask, QRegion region, const QRect& rect )
|
void GLTexture::render( QRegion region, const QRect& rect )
|
||||||
{
|
|
||||||
return render( !( mask & ( Effect::PAINT_WINDOW_TRANSFORMED | Effect::PAINT_SCREEN_TRANSFORMED )),
|
|
||||||
region, rect );
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLTexture::render( bool clip, QRegion region, const QRect& rect )
|
|
||||||
{
|
{
|
||||||
const float verts[ 4 * 2 ] =
|
const float verts[ 4 * 2 ] =
|
||||||
{
|
{
|
||||||
|
@ -522,7 +485,7 @@ void GLTexture::render( bool clip, QRegion region, const QRect& rect )
|
||||||
1, 0,
|
1, 0,
|
||||||
1, 1
|
1, 1
|
||||||
};
|
};
|
||||||
renderGLGeometry( clip, region, 4, verts, texcoords );
|
renderGLGeometry( region, 4, verts, texcoords );
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLTexture::enableUnnormalizedTexCoords()
|
void GLTexture::enableUnnormalizedTexCoords()
|
||||||
|
|
|
@ -82,22 +82,17 @@ int KWIN_EXPORT nearestPowerOfTwo( int x );
|
||||||
* @param stride byte offset of consecutive elements in arrays. If 0, then
|
* @param stride byte offset of consecutive elements in arrays. If 0, then
|
||||||
* arrays must be tighly packed. Stride must be a multiple of sizeof(float)!
|
* arrays must be tighly packed. Stride must be a multiple of sizeof(float)!
|
||||||
**/
|
**/
|
||||||
KWIN_EXPORT void renderGLGeometry( bool clip, const QRegion& region, int count,
|
KWIN_EXPORT void renderGLGeometry( const QRegion& region, int count,
|
||||||
const float* vertices, const float* texture = 0, const float* color = 0,
|
const float* vertices, const float* texture = 0, const float* color = 0,
|
||||||
int dim = 2, int stride = 0 );
|
int dim = 2, int stride = 0 );
|
||||||
/**
|
/**
|
||||||
* Same as above, sets clip parameter according to mask.
|
* Same as above, renders without specified region
|
||||||
**/
|
|
||||||
KWIN_EXPORT void renderGLGeometry( int mask, const QRegion& region, int count,
|
|
||||||
const float* vertices, const float* texture = 0, const float* color = 0,
|
|
||||||
int dim = 2, int stride = 0 );
|
|
||||||
/**
|
|
||||||
* Same as above, renders without clipping
|
|
||||||
**/
|
**/
|
||||||
KWIN_EXPORT void renderGLGeometry( int count,
|
KWIN_EXPORT void renderGLGeometry( int count,
|
||||||
const float* vertices, const float* texture = 0, const float* color = 0,
|
const float* vertices, const float* texture = 0, const float* color = 0,
|
||||||
int dim = 2, int stride = 0 );
|
int dim = 2, int stride = 0 );
|
||||||
|
|
||||||
|
|
||||||
KWIN_EXPORT void renderGLGeometryImmediate( int count,
|
KWIN_EXPORT void renderGLGeometryImmediate( int count,
|
||||||
const float* vertices, const float* texture = 0, const float* color = 0,
|
const float* vertices, const float* texture = 0, const float* color = 0,
|
||||||
int dim = 2, int stride = 0 );
|
int dim = 2, int stride = 0 );
|
||||||
|
@ -125,8 +120,7 @@ class KWIN_EXPORT GLTexture
|
||||||
virtual void discard();
|
virtual void discard();
|
||||||
virtual void bind();
|
virtual void bind();
|
||||||
virtual void unbind();
|
virtual void unbind();
|
||||||
void render( bool clip, QRegion region, const QRect& rect );
|
void render( QRegion region, const QRect& rect );
|
||||||
void render( int mask, QRegion region, const QRect& rect );
|
|
||||||
void enableUnnormalizedTexCoords();
|
void enableUnnormalizedTexCoords();
|
||||||
void disableUnnormalizedTexCoords();
|
void disableUnnormalizedTexCoords();
|
||||||
|
|
||||||
|
|
|
@ -135,6 +135,8 @@ void Scene::paintScreen( int* mask, QRegion* region )
|
||||||
*region |= painted_region;
|
*region |= painted_region;
|
||||||
// make sure not to go outside of the screen area
|
// make sure not to go outside of the screen area
|
||||||
*region &= QRegion( 0, 0, displayWidth(), displayHeight());
|
*region &= QRegion( 0, 0, displayWidth(), displayHeight());
|
||||||
|
// make sure all clipping is restored
|
||||||
|
Q_ASSERT( !PaintClipper::clip());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute time since the last painting pass.
|
// Compute time since the last painting pass.
|
||||||
|
|
8
scene.h
8
scene.h
|
@ -105,8 +105,6 @@ class Scene
|
||||||
virtual void paintWindow( Window* w, int mask, QRegion region, WindowQuadList quads );
|
virtual void paintWindow( Window* w, int mask, QRegion region, WindowQuadList quads );
|
||||||
// called after all effects had their drawWindow() called
|
// called after all effects had their drawWindow() called
|
||||||
void finalDrawWindow( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data );
|
void finalDrawWindow( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data );
|
||||||
// infinite region, i.e. everything
|
|
||||||
static QRegion infiniteRegion();
|
|
||||||
// compute time since the last repaint
|
// compute time since the last repaint
|
||||||
void updateTimeDiff();
|
void updateTimeDiff();
|
||||||
// saved data for 2nd pass of optimized screen painting
|
// saved data for 2nd pass of optimized screen painting
|
||||||
|
@ -197,12 +195,6 @@ class Scene::Window
|
||||||
|
|
||||||
extern Scene* scene;
|
extern Scene* scene;
|
||||||
|
|
||||||
inline
|
|
||||||
QRegion Scene::infiniteRegion()
|
|
||||||
{ // INT_MIN / 2 because width/height is used (INT_MIN+INT_MAX==-1)
|
|
||||||
return QRegion( INT_MIN / 2, INT_MIN / 2, INT_MAX, INT_MAX );
|
|
||||||
}
|
|
||||||
|
|
||||||
inline
|
inline
|
||||||
int Scene::Window::x() const
|
int Scene::Window::x() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -723,22 +723,24 @@ void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
|
||||||
|
|
||||||
void SceneOpenGL::paintBackground( QRegion region )
|
void SceneOpenGL::paintBackground( QRegion region )
|
||||||
{
|
{
|
||||||
if( region == infiniteRegion())
|
PaintClipper pc( region );
|
||||||
|
if( !PaintClipper::clip())
|
||||||
{
|
{
|
||||||
glClearColor( 0, 0, 0, 1 ); // black
|
glClearColor( 0, 0, 0, 1 ); // black
|
||||||
glClear( GL_COLOR_BUFFER_BIT );
|
glClear( GL_COLOR_BUFFER_BIT );
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else
|
glColor4f( 0, 0, 0, 1 ); // black
|
||||||
|
for( PaintClipper::Iterator iterator;
|
||||||
|
!iterator.isDone();
|
||||||
|
iterator.next())
|
||||||
{
|
{
|
||||||
glColor4f( 0, 0, 0, 1 ); // black
|
|
||||||
glBegin( GL_QUADS );
|
glBegin( GL_QUADS );
|
||||||
foreach( QRect r, region.rects())
|
QRect r = iterator.boundingRect();
|
||||||
{
|
glVertex2i( r.x(), r.y());
|
||||||
glVertex2i( r.x(), r.y());
|
glVertex2i( r.x() + r.width(), r.y());
|
||||||
glVertex2i( r.x() + r.width(), r.y());
|
glVertex2i( r.x() + r.width(), r.y() + r.height());
|
||||||
glVertex2i( r.x() + r.width(), r.y() + r.height());
|
glVertex2i( r.x(), r.y() + r.height());
|
||||||
glVertex2i( r.x(), r.y() + r.height());
|
|
||||||
}
|
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1257,7 +1259,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::renderQuads( int mask, const QRegion& region, const WindowQuadList& quads )
|
void SceneOpenGL::Window::renderQuads( int, const QRegion& region, const WindowQuadList& quads )
|
||||||
{
|
{
|
||||||
if( quads.isEmpty())
|
if( quads.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -1265,7 +1267,7 @@ void SceneOpenGL::Window::renderQuads( int mask, const QRegion& region, const Wi
|
||||||
float* vertices;
|
float* vertices;
|
||||||
float* texcoords;
|
float* texcoords;
|
||||||
quads.makeArrays( &vertices, &texcoords );
|
quads.makeArrays( &vertices, &texcoords );
|
||||||
renderGLGeometry( mask, region, quads.count() * 4,
|
renderGLGeometry( region, quads.count() * 4,
|
||||||
vertices, texcoords, NULL, 2, 0 );
|
vertices, texcoords, NULL, 2, 0 );
|
||||||
delete[] vertices;
|
delete[] vertices;
|
||||||
delete[] texcoords;
|
delete[] texcoords;
|
||||||
|
|
|
@ -267,15 +267,14 @@ void SceneXrender::paintTransformedScreen( int orig_mask )
|
||||||
// fill the screen background
|
// fill the screen background
|
||||||
void SceneXrender::paintBackground( QRegion region )
|
void SceneXrender::paintBackground( QRegion region )
|
||||||
{
|
{
|
||||||
if( region != infiniteRegion())
|
PaintClipper pc( region );
|
||||||
|
for( PaintClipper::Iterator iterator;
|
||||||
|
!iterator.isDone();
|
||||||
|
iterator.next())
|
||||||
{
|
{
|
||||||
XserverRegion background_region = toXserverRegion( region );
|
XRenderColor col = { 0, 0, 0, 0xffff }; // black
|
||||||
XFixesSetPictureClipRegion( display(), buffer, 0, 0, background_region );
|
XRenderFillRectangle( display(), PictOpSrc, buffer, &col, 0, 0, displayWidth(), displayHeight());
|
||||||
XFixesDestroyRegion( display(), background_region );
|
|
||||||
}
|
}
|
||||||
XRenderColor col = { 0, 0, 0, 0xffff }; // black
|
|
||||||
XRenderFillRectangle( display(), PictOpSrc, buffer, &col, 0, 0, displayWidth(), displayHeight());
|
|
||||||
XFixesSetPictureClipRegion( display(), buffer, 0, 0, None );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneXrender::windowGeometryShapeChanged( Toplevel* c )
|
void SceneXrender::windowGeometryShapeChanged( Toplevel* c )
|
||||||
|
@ -326,27 +325,6 @@ void SceneXrender::windowAdded( Toplevel* c )
|
||||||
c->effectWindow()->setSceneWindow( windows[ c ]);
|
c->effectWindow()->setSceneWindow( windows[ c ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert QRegion to XserverRegion. This code uses XserverRegion
|
|
||||||
// only when really necessary as the shared implementation uses
|
|
||||||
// QRegion.
|
|
||||||
XserverRegion SceneXrender::toXserverRegion( QRegion region )
|
|
||||||
{
|
|
||||||
QVector< QRect > rects = region.rects();
|
|
||||||
XRectangle* xr = new XRectangle[ rects.count() ];
|
|
||||||
for( int i = 0;
|
|
||||||
i < rects.count();
|
|
||||||
++i )
|
|
||||||
{
|
|
||||||
xr[ i ].x = rects[ i ].x();
|
|
||||||
xr[ i ].y = rects[ i ].y();
|
|
||||||
xr[ i ].width = rects[ i ].width();
|
|
||||||
xr[ i ].height = rects[ i ].height();
|
|
||||||
}
|
|
||||||
XserverRegion ret = XFixesCreateRegion( display(), xr, rects.count());
|
|
||||||
delete[] xr;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//****************************************
|
//****************************************
|
||||||
// SceneXrender::Window
|
// SceneXrender::Window
|
||||||
//****************************************
|
//****************************************
|
||||||
|
@ -451,12 +429,6 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa
|
||||||
if( opaque )
|
if( opaque )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( region != infiniteRegion())
|
|
||||||
{
|
|
||||||
XserverRegion clip_region = toXserverRegion( region );
|
|
||||||
XFixesSetPictureClipRegion( display(), buffer, 0, 0, clip_region );
|
|
||||||
XFixesDestroyRegion( display(), clip_region );
|
|
||||||
}
|
|
||||||
Picture pic = picture(); // get XRender picture
|
Picture pic = picture(); // get XRender picture
|
||||||
if( pic == None ) // The render format can be null for GL and/or Xv visuals
|
if( pic == None ) // The render format can be null for GL and/or Xv visuals
|
||||||
return;
|
return;
|
||||||
|
@ -522,17 +494,23 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa
|
||||||
}
|
}
|
||||||
if( x != toplevel->x() || y != toplevel->y())
|
if( x != toplevel->x() || y != toplevel->y())
|
||||||
transformed_shape.translate( x, y );
|
transformed_shape.translate( x, y );
|
||||||
if( opaque )
|
PaintClipper pc( region );
|
||||||
|
for( PaintClipper::Iterator iterator;
|
||||||
|
!iterator.isDone();
|
||||||
|
iterator.next())
|
||||||
{
|
{
|
||||||
XRenderComposite( display(), PictOpSrc, pic, None, buffer, 0, 0, 0, 0,
|
if( opaque )
|
||||||
x, y, width, height);
|
{
|
||||||
}
|
XRenderComposite( display(), PictOpSrc, pic, None, buffer, 0, 0, 0, 0,
|
||||||
else
|
x, y, width, height);
|
||||||
{
|
}
|
||||||
Picture alpha = alphaMask( data.opacity );
|
else
|
||||||
XRenderComposite( display(), PictOpOver, pic, alpha, buffer, 0, 0, 0, 0,
|
{
|
||||||
x, y, width, height);
|
Picture alpha = alphaMask( data.opacity );
|
||||||
transformed_shape = QRegion();
|
XRenderComposite( display(), PictOpOver, pic, alpha, buffer, 0, 0, 0, 0,
|
||||||
|
x, y, width, height);
|
||||||
|
transformed_shape = QRegion();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( xscale != 1 || yscale != 1 )
|
if( xscale != 1 || yscale != 1 )
|
||||||
{
|
{
|
||||||
|
@ -545,7 +523,6 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa
|
||||||
if( filter == ImageFilterGood )
|
if( filter == ImageFilterGood )
|
||||||
XRenderSetPictureFilter( display(), pic, const_cast< char* >( "fast" ), NULL, 0 );
|
XRenderSetPictureFilter( display(), pic, const_cast< char* >( "fast" ), NULL, 0 );
|
||||||
}
|
}
|
||||||
XFixesSetPictureClipRegion( display(), buffer, 0, 0, None );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -54,7 +54,6 @@ class SceneXrender
|
||||||
private:
|
private:
|
||||||
void paintTransformedScreen( int mask );
|
void paintTransformedScreen( int mask );
|
||||||
void createBuffer();
|
void createBuffer();
|
||||||
static XserverRegion toXserverRegion( QRegion region );
|
|
||||||
XRenderPictFormat* format;
|
XRenderPictFormat* format;
|
||||||
Picture front;
|
Picture front;
|
||||||
static Picture buffer;
|
static Picture buffer;
|
||||||
|
|
Loading…
Reference in a new issue