Use xRenderBlendPicture as alpha mask in SceneXrender
Less duplicated functionality.
This commit is contained in:
parent
577a7030b6
commit
ce930dfc8a
2 changed files with 10 additions and 47 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue