Use xRenderBlendPicture as alpha mask in SceneXrender

Less duplicated functionality.
icc-effect-5.14.5
Martin Gräßlin 2013-02-27 12:10:22 +01:00
parent 577a7030b6
commit ce930dfc8a
2 changed files with 10 additions and 47 deletions

View File

@ -226,15 +226,11 @@ void SceneXrender::windowGeometryShapeChanged(KWin::Toplevel* c)
Window* w = windows[ c ]; Window* w = windows[ c ];
w->discardPicture(); w->discardPicture();
w->discardShape(); w->discardShape();
w->discardAlpha();
} }
void SceneXrender::windowOpacityChanged(KWin::Toplevel* c) void SceneXrender::windowOpacityChanged(KWin::Toplevel* c)
{ {
if (!windows.contains(c)) // this is ok, alpha is created on demand Q_UNUSED(c)
return;
Window* w = windows[ c ];
w->discardAlpha();
} }
void SceneXrender::windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted) void SceneXrender::windowClosed(KWin::Toplevel* c, KWin::Deleted* deleted)
@ -265,7 +261,6 @@ void SceneXrender::windowAdded(Toplevel* c)
{ {
assert(!windows.contains(c)); assert(!windows.contains(c));
windows[ c ] = new Window(c); windows[ c ] = new Window(c);
connect(c, SIGNAL(opacityChanged(KWin::Toplevel*,qreal)), SLOT(windowOpacityChanged(KWin::Toplevel*)));
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(windowGeometryShapeChanged(KWin::Toplevel*))); connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), SLOT(windowGeometryShapeChanged(KWin::Toplevel*)));
connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(windowClosed(KWin::Toplevel*,KWin::Deleted*))); connect(c, SIGNAL(windowClosed(KWin::Toplevel*,KWin::Deleted*)), SLOT(windowClosed(KWin::Toplevel*,KWin::Deleted*)));
c->effectWindow()->setSceneWindow(windows[ c ]); c->effectWindow()->setSceneWindow(windows[ c ]);
@ -284,7 +279,6 @@ SceneXrender::Window::Window(Toplevel* c)
: Scene::Window(c) : Scene::Window(c)
, _picture(None) , _picture(None)
, format(XRenderFindVisualFormat(display(), c->visual())) , format(XRenderFindVisualFormat(display(), c->visual()))
, alpha(None)
, alpha_cached_opacity(0.0) , alpha_cached_opacity(0.0)
{ {
} }
@ -292,7 +286,6 @@ SceneXrender::Window::Window(Toplevel* c)
SceneXrender::Window::~Window() SceneXrender::Window::~Window()
{ {
discardPicture(); discardPicture();
discardAlpha();
discardShape(); discardShape();
} }
@ -328,39 +321,6 @@ void SceneXrender::Window::discardPicture()
_picture = None; _picture = None;
} }
void SceneXrender::Window::discardAlpha()
{
if (alpha != None)
XRenderFreePicture(display(), alpha);
alpha = None;
}
// Create XRender picture for the alpha mask.
Picture SceneXrender::Window::alphaMask(double opacity)
{
if (isOpaque() && qFuzzyCompare(opacity, 1.0))
return None;
bool created = false;
if (alpha == None) {
// Create a 1x1 8bpp pixmap containing the given opacity in the alpha channel.
Pixmap pixmap = XCreatePixmap(display(), rootWindow(), 1, 1, 8);
XRenderPictFormat* format = XRenderFindStandardFormat(display(), PictStandardA8);
XRenderPictureAttributes pa;
pa.repeat = True;
alpha = XRenderCreatePicture(display(), pixmap, format, CPRepeat, &pa);
XFreePixmap(display(), pixmap);
created = true;
}
if (created || !qFuzzyCompare(alpha_cached_opacity + 1.0, opacity + 1.0)) {
XRenderColor col;
col.alpha = int(opacity * 0xffff);
XRenderFillRectangle(display(), PictOpSrc, alpha, &col, 0, 0, 1, 1);
alpha_cached_opacity = opacity;
}
return alpha;
}
// Maps window coordinates to screen coordinates // Maps window coordinates to screen coordinates
QRect SceneXrender::Window::mapToScreen(int mask, const WindowPaintData &data, const QRect &rect) const QRect SceneXrender::Window::mapToScreen(int mask, const WindowPaintData &data, const QRect &rect) const
{ {
@ -656,7 +616,10 @@ XRenderComposite(display(), PictOpOver, m_xrenderShadow->shadowPixmap(SceneXRend
//shadow //shadow
if (wantShadow) { if (wantShadow) {
Picture shadowAlpha = opaque ? None : alphaMask(data.opacity()); xcb_render_picture_t shadowAlpha = XCB_RENDER_PICTURE_NONE;
if (!opaque) {
shadowAlpha = xRenderBlendPicture(data.opacity());
}
RENDER_SHADOW_TILE(TopLeft, stlr); RENDER_SHADOW_TILE(TopLeft, stlr);
RENDER_SHADOW_TILE(Top, str); RENDER_SHADOW_TILE(Top, str);
RENDER_SHADOW_TILE(TopRight, strr); RENDER_SHADOW_TILE(TopRight, strr);
@ -670,7 +633,10 @@ XRenderComposite(display(), PictOpOver, m_xrenderShadow->shadowPixmap(SceneXRend
// Paint the window contents // Paint the window contents
if (!(client && client->isShade())) { if (!(client && client->isShade())) {
Picture clientAlpha = opaque ? None : alphaMask(data.opacity()); xcb_render_picture_t clientAlpha = XCB_RENDER_PICTURE_NONE;
if (!opaque) {
clientAlpha = xRenderBlendPicture(data.opacity());
}
XRenderComposite(display(), clientRenderOp, pic, clientAlpha, renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height()); XRenderComposite(display(), clientRenderOp, pic, clientAlpha, renderTarget, cr.x(), cr.y(), 0, 0, dr.x(), dr.y(), dr.width(), dr.height());
if (!opaque) if (!opaque)
transformed_shape = QRegion(); transformed_shape = QRegion();
@ -682,7 +648,7 @@ XRenderComposite(display(), PictOpOver, _PART_, decorationAlpha, renderTarget,\
if (client || deleted) { if (client || deleted) {
if (!noBorder) { if (!noBorder) {
Picture decorationAlpha = alphaMask(data.opacity() * data.decorationOpacity()); xcb_render_picture_t decorationAlpha = xRenderBlendPicture(data.opacity() * data.decorationOpacity());
RENDER_DECO_PART(top, dtr); RENDER_DECO_PART(top, dtr);
RENDER_DECO_PART(left, dlr); RENDER_DECO_PART(left, dlr);
RENDER_DECO_PART(right, drr); RENDER_DECO_PART(right, drr);

View File

@ -81,19 +81,16 @@ public:
virtual ~Window(); virtual ~Window();
virtual void performPaint(int mask, QRegion region, WindowPaintData data); virtual void performPaint(int mask, QRegion region, WindowPaintData data);
void discardPicture(); void discardPicture();
void discardAlpha();
QRegion transformedShape() const; QRegion transformedShape() const;
void setTransformedShape(const QRegion& shape); void setTransformedShape(const QRegion& shape);
static void cleanup(); static void cleanup();
private: private:
Picture picture(); Picture picture();
Picture alphaMask(double opacity);
QRect mapToScreen(int mask, const WindowPaintData &data, const QRect &rect) const; QRect mapToScreen(int mask, const WindowPaintData &data, const QRect &rect) const;
QPoint mapToScreen(int mask, const WindowPaintData &data, const QPoint &point) const; QPoint mapToScreen(int mask, const WindowPaintData &data, const QPoint &point) const;
void prepareTempPixmap(); void prepareTempPixmap();
Picture _picture; Picture _picture;
XRenderPictFormat* format; XRenderPictFormat* format;
Picture alpha;
double alpha_cached_opacity; double alpha_cached_opacity;
QRegion transformed_shape; QRegion transformed_shape;
static QRect temp_visibleRect; static QRect temp_visibleRect;