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
icc-effect-5.14.5
Luboš Luňák 2008-02-25 11:32:21 +00:00
parent 73ad1f1adc
commit cff2b0e6cd
19 changed files with 347 additions and 162 deletions

View File

@ -261,7 +261,7 @@ void CoverSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
frameRect.y() + frameRect.height()*0.1f,
frameRect.height()*0.8f,
frameRect.height()*0.8f );
icon->render( false, region, iconRect);
icon->render( region, iconRect);
icon->unbind();
glDisable( GL_BLEND );
glPopAttrib();

View File

@ -146,11 +146,19 @@ void DesktopGridEffect::paintScreen( int mask, QRegion region, ScreenPaintData&
++desktop )
{
if( desktop != desktop_with_move )
{
PaintClipper pc( desktopRect( desktop, true ));
paintScreenDesktop( desktop, mask, region, data );
}
}
// paint the desktop with the window being moved as the last one, i.e. on top of others
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 );
}
}
void DesktopGridEffect::paintScreenDesktop( int desktop, int mask, QRegion region, ScreenPaintData data )

View File

@ -363,7 +363,7 @@ void FlipSwitchEffect::paintScreen( int mask, QRegion region, ScreenPaintData& d
frameRect.y() + frameRect.height()*0.1f,
frameRect.height()*0.8f,
frameRect.height()*0.8f );
icon->render( false, region, iconRect);
icon->render( region, iconRect);
icon->unbind();
glPopAttrib();
#endif

View File

@ -81,13 +81,8 @@ void MagnifierEffect::paintScreen( int mask, QRegion region, ScreenPaintData& da
effects->paintScreen( mask, region, data ); // paint normal screen
if( zoom != 1.0 )
{ // paint magnifier
// ## TODO this should be inside KWIN_HAVE_OPENGL_COMPOSITING
glPushAttrib( GL_ENABLE_BIT );
QRect area = magnifierArea();
glEnable( GL_SCISSOR_TEST );
int dh = displayHeight();
// Scissor rect has to be given in OpenGL coords
glScissor( area.x(), dh - area.y() - area.height(), area.width(), area.height());
PaintClipper::push( area ); // don't allow any painting outside of the area
mask |= PAINT_SCREEN_TRANSFORMED;
data2.xScale *= 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.yTranslate = - int( cursor.y() * ( zoom - 1 ));
effects->paintScreen( mask, region, data2 );
glPopAttrib();
PaintClipper::pop( area );
// ## TODO this should be inside KWIN_HAVE_OPENGL_COMPOSITING
glPushAttrib( GL_CURRENT_BIT );
glColor4f( 0, 0, 0, 1 ); // black
glBegin( GL_QUADS );
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // top frame
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
glVertex2i( area.right() + FRAME_WIDTH, area.top() - 1 );
glVertex2i( area.left() - FRAME_WIDTH, area.top() - 1 );
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // left frame
glVertex2i( area.left() - 1, area.top() - FRAME_WIDTH );
glVertex2i( area.left() - 1, area.bottom() + FRAME_WIDTH );
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
glVertex2i( area.right() + 1, area.top() - FRAME_WIDTH ); // right frame
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
glVertex2i( area.right() + 1, area.bottom() + FRAME_WIDTH );
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();
for( PaintClipper::Iterator iterator;
!iterator.isDone();
iterator.next())
{
glBegin( GL_QUADS );
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // top frame
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
glVertex2i( area.right() + FRAME_WIDTH, area.top() - 1 );
glVertex2i( area.left() - FRAME_WIDTH, area.top() - 1 );
glVertex2i( area.left() - FRAME_WIDTH, area.top() - FRAME_WIDTH ); // left frame
glVertex2i( area.left() - 1, area.top() - FRAME_WIDTH );
glVertex2i( area.left() - 1, area.bottom() + FRAME_WIDTH );
glVertex2i( area.left() - FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
glVertex2i( area.right() + 1, area.top() - FRAME_WIDTH ); // right frame
glVertex2i( area.right() + FRAME_WIDTH, area.top() - FRAME_WIDTH );
glVertex2i( area.right() + FRAME_WIDTH, area.bottom() + FRAME_WIDTH );
glVertex2i( area.right() + 1, area.bottom() + FRAME_WIDTH );
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();
}
}

View File

@ -149,7 +149,7 @@ void PresentWindowsEffect::paintScreen( int mask, QRegion region, ScreenPaintDat
renderRoundBoxWithEdge( filterFrameRect );
// And then the text on top of it
filterTexture->bind();
filterTexture->render( mask, region, filterTextureRect );
filterTexture->render( region, filterTextureRect );
filterTexture->unbind();
glPopAttrib();
}

View File

@ -89,7 +89,7 @@ void ShadowEffect::drawWindow( EffectWindow* w, int mask, QRegion region, Window
{
// For translucent windows, shadow needs to be drawn before the
// window itself.
drawShadow( w, mask, region, data, false );
drawShadow( w, mask, region, data );
}
else
{
@ -145,7 +145,7 @@ void ShadowEffect::drawQueuedShadows( EffectWindow* behindWindow )
// that are behind that window.
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
{
@ -155,7 +155,7 @@ void ShadowEffect::drawQueuedShadows( EffectWindow* behindWindow )
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 );
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);
// We have two elements per vertex in the verts array
int verticesCount = verts.count() / 2;
if( clip )
renderGLGeometry( true, region, verticesCount, verts.data(), texcoords.data() );
else
renderGLGeometry( mask, region, verticesCount, verts.data(), texcoords.data() );
renderGLGeometry( region, verticesCount, verts.data(), texcoords.data() );
mShadowTexture->unbind();
glPopMatrix();

View File

@ -40,7 +40,7 @@ class ShadowEffect
virtual void windowClosed( EffectWindow* c );
virtual QRect transformWindowDamage( EffectWindow* w, const QRect& r );
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;
// transforms window rect -> shadow rect
QRect shadowRectangle(const QRect& windowRectangle) const;

View File

@ -439,7 +439,7 @@ void ShowFpsEffect::paintFPSText(int fps)
delete fpsText;
fpsText = new GLTexture(im);
fpsText->bind();
fpsText->render(false, QRegion(fpsTextRect), fpsTextRect);
fpsText->render(QRegion(fpsTextRect), fpsTextRect);
fpsText->unbind();
effects->addRepaint(fpsTextRect);
#endif

View File

@ -142,7 +142,7 @@ void SnowEffect::paintScreen( int mask, QRegion region, ScreenPaintData& data )
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
for (int i=0; i<flakes->count(); i++)
{
texture->render( false, region, flakes->at(i));
texture->render( region, flakes->at(i));
}
texture->unbind();
glPopAttrib();

View File

@ -77,7 +77,7 @@ void TrackMouseEffect::paintScreen( int mask, QRegion region, ScreenPaintData& d
++i )
{
QRect r = starRect( i );
texture->render( mask, region, r );
texture->render( region, r );
}
texture->unbind();
glPopAttrib();

View File

@ -677,4 +677,168 @@ bool WindowQuadList::smoothNeeded() const
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

View File

@ -32,12 +32,17 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QtCore/QVector>
#include <QtCore/QList>
#include <QtCore/QHash>
#include <QtCore/QStack>
#include <KDE/KPluginFactory>
#include <KDE/KShortcutsEditor>
#include <assert.h>
#include <limits.h>
#ifdef KWIN_HAVE_XRENDER_COMPOSITING
#include <X11/extensions/Xfixes.h>
#endif
class KLibrary;
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_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( \
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
*
@ -822,6 +843,71 @@ class KWIN_EXPORT ScreenPrePaintData
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.
**/

View File

@ -128,18 +128,10 @@ int nearestPowerOfTwo( int x )
void renderGLGeometry( int count, const float* vertices, const float* texture, const float* color,
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,
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,
void renderGLGeometry( const QRegion& region, int count,
const float* vertices, const float* texture, const float* color,
int dim, int stride )
{
@ -166,40 +158,17 @@ void renderGLGeometry( bool clip, const QRegion& region, int count,
}
}
// Render
if( !clip )
// Clip using scissoring
PaintClipper pc( region );
for( PaintClipper::Iterator iterator;
!iterator.isDone();
iterator.next())
{
// Just draw the entire window, no clipping
if( use_arrays )
glDrawArrays( GL_QUADS, 0, count );
else
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 )
{
@ -500,13 +469,7 @@ void GLTexture::unbind()
glDisable( mTarget );
}
void GLTexture::render( int mask, 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 )
void GLTexture::render( QRegion region, const QRect& rect )
{
const float verts[ 4 * 2 ] =
{
@ -522,7 +485,7 @@ void GLTexture::render( bool clip, QRegion region, const QRect& rect )
1, 0,
1, 1
};
renderGLGeometry( clip, region, 4, verts, texcoords );
renderGLGeometry( region, 4, verts, texcoords );
}
void GLTexture::enableUnnormalizedTexCoords()

View File

@ -82,22 +82,17 @@ int KWIN_EXPORT nearestPowerOfTwo( int x );
* @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)!
**/
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,
int dim = 2, int stride = 0 );
/**
* Same as above, sets clip parameter according to mask.
**/
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
* Same as above, renders without specified region
**/
KWIN_EXPORT void renderGLGeometry( int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
KWIN_EXPORT void renderGLGeometryImmediate( int count,
const float* vertices, const float* texture = 0, const float* color = 0,
int dim = 2, int stride = 0 );
@ -125,8 +120,7 @@ class KWIN_EXPORT GLTexture
virtual void discard();
virtual void bind();
virtual void unbind();
void render( bool clip, QRegion region, const QRect& rect );
void render( int mask, QRegion region, const QRect& rect );
void render( QRegion region, const QRect& rect );
void enableUnnormalizedTexCoords();
void disableUnnormalizedTexCoords();

View File

@ -135,6 +135,8 @@ void Scene::paintScreen( int* mask, QRegion* region )
*region |= painted_region;
// make sure not to go outside of the screen area
*region &= QRegion( 0, 0, displayWidth(), displayHeight());
// make sure all clipping is restored
Q_ASSERT( !PaintClipper::clip());
}
// Compute time since the last painting pass.

View File

@ -105,8 +105,6 @@ class Scene
virtual void paintWindow( Window* w, int mask, QRegion region, WindowQuadList quads );
// called after all effects had their drawWindow() called
void finalDrawWindow( EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data );
// infinite region, i.e. everything
static QRegion infiniteRegion();
// compute time since the last repaint
void updateTimeDiff();
// saved data for 2nd pass of optimized screen painting
@ -197,12 +195,6 @@ class Scene::Window
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
int Scene::Window::x() const
{

View File

@ -723,22 +723,24 @@ void SceneOpenGL::paintGenericScreen( int mask, ScreenPaintData data )
void SceneOpenGL::paintBackground( QRegion region )
{
if( region == infiniteRegion())
PaintClipper pc( region );
if( !PaintClipper::clip())
{
glClearColor( 0, 0, 0, 1 ); // black
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 );
foreach( QRect r, region.rects())
{
glVertex2i( r.x(), r.y());
glVertex2i( r.x() + r.width(), r.y());
glVertex2i( r.x() + r.width(), r.y() + r.height());
glVertex2i( r.x(), r.y() + r.height());
}
QRect r = iterator.boundingRect();
glVertex2i( r.x(), r.y());
glVertex2i( r.x() + r.width(), r.y());
glVertex2i( r.x() + r.width(), r.y() + r.height());
glVertex2i( r.x(), r.y() + r.height());
glEnd();
}
}
@ -1257,7 +1259,7 @@ void SceneOpenGL::Window::performPaint( int mask, QRegion region, WindowPaintDat
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())
return;
@ -1265,7 +1267,7 @@ void SceneOpenGL::Window::renderQuads( int mask, const QRegion& region, const Wi
float* vertices;
float* texcoords;
quads.makeArrays( &vertices, &texcoords );
renderGLGeometry( mask, region, quads.count() * 4,
renderGLGeometry( region, quads.count() * 4,
vertices, texcoords, NULL, 2, 0 );
delete[] vertices;
delete[] texcoords;

View File

@ -267,15 +267,14 @@ void SceneXrender::paintTransformedScreen( int orig_mask )
// fill the screen background
void SceneXrender::paintBackground( QRegion region )
{
if( region != infiniteRegion())
PaintClipper pc( region );
for( PaintClipper::Iterator iterator;
!iterator.isDone();
iterator.next())
{
XserverRegion background_region = toXserverRegion( region );
XFixesSetPictureClipRegion( display(), buffer, 0, 0, background_region );
XFixesDestroyRegion( display(), background_region );
XRenderColor col = { 0, 0, 0, 0xffff }; // black
XRenderFillRectangle( display(), PictOpSrc, buffer, &col, 0, 0, displayWidth(), displayHeight());
}
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 )
@ -326,27 +325,6 @@ void SceneXrender::windowAdded( Toplevel* 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
//****************************************
@ -451,12 +429,6 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa
if( opaque )
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
if( pic == None ) // The render format can be null for GL and/or Xv visuals
return;
@ -522,17 +494,23 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa
}
if( x != toplevel->x() || y != toplevel->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,
x, y, width, height);
}
else
{
Picture alpha = alphaMask( data.opacity );
XRenderComposite( display(), PictOpOver, pic, alpha, buffer, 0, 0, 0, 0,
x, y, width, height);
transformed_shape = QRegion();
if( opaque )
{
XRenderComposite( display(), PictOpSrc, pic, None, buffer, 0, 0, 0, 0,
x, y, width, height);
}
else
{
Picture alpha = alphaMask( data.opacity );
XRenderComposite( display(), PictOpOver, pic, alpha, buffer, 0, 0, 0, 0,
x, y, width, height);
transformed_shape = QRegion();
}
}
if( xscale != 1 || yscale != 1 )
{
@ -545,7 +523,6 @@ void SceneXrender::Window::performPaint( int mask, QRegion region, WindowPaintDa
if( filter == ImageFilterGood )
XRenderSetPictureFilter( display(), pic, const_cast< char* >( "fast" ), NULL, 0 );
}
XFixesSetPictureClipRegion( display(), buffer, 0, 0, None );
}
} // namespace

View File

@ -54,7 +54,6 @@ class SceneXrender
private:
void paintTransformedScreen( int mask );
void createBuffer();
static XserverRegion toXserverRegion( QRegion region );
XRenderPictFormat* format;
Picture front;
static Picture buffer;