Merge branch 'KDE/4.7'
Conflicts: kwin/libkwineffects/kwinglutils.cpp kwin/libkwineffects/kwinglutils.h
This commit is contained in:
commit
08b2aebd30
7 changed files with 211 additions and 89 deletions
|
@ -426,6 +426,11 @@ QImage GLTexture::convertToGLFormat(const QImage& img) const
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLTexture::isYInverted() const
|
||||||
|
{
|
||||||
|
return y_inverted;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace KWin
|
} // namespace KWin
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -60,6 +60,10 @@ public:
|
||||||
int height() const {
|
int height() const {
|
||||||
return mSize.height(); /// @since 4.5
|
return mSize.height(); /// @since 4.5
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @since 4.7
|
||||||
|
**/
|
||||||
|
bool isYInverted() const;
|
||||||
|
|
||||||
virtual bool load(const QImage& image, GLenum target = GL_TEXTURE_2D);
|
virtual bool load(const QImage& image, GLenum target = GL_TEXTURE_2D);
|
||||||
virtual bool load(const QPixmap& pixmap, GLenum target = GL_TEXTURE_2D);
|
virtual bool load(const QPixmap& pixmap, GLenum target = GL_TEXTURE_2D);
|
||||||
|
|
242
scene_opengl.cpp
242
scene_opengl.cpp
|
@ -513,14 +513,7 @@ void SceneOpenGL::Window::performPaint(int mask, QRegion region, WindowPaintData
|
||||||
|
|
||||||
// shadow
|
// shadow
|
||||||
if (m_shadow) {
|
if (m_shadow) {
|
||||||
paintShadow(WindowQuadShadowTop, region, data);
|
paintShadow(region, data);
|
||||||
paintShadow(WindowQuadShadowTopRight, region, data);
|
|
||||||
paintShadow(WindowQuadShadowRight, region, data);
|
|
||||||
paintShadow(WindowQuadShadowBottomRight, region, data);
|
|
||||||
paintShadow(WindowQuadShadowBottom, region, data);
|
|
||||||
paintShadow(WindowQuadShadowBottomLeft, region, data);
|
|
||||||
paintShadow(WindowQuadShadowLeft, region, data);
|
|
||||||
paintShadow(WindowQuadShadowTopLeft, region, data);
|
|
||||||
}
|
}
|
||||||
// decorations
|
// decorations
|
||||||
Client *client = dynamic_cast<Client*>(toplevel);
|
Client *client = dynamic_cast<Client*>(toplevel);
|
||||||
|
@ -659,10 +652,17 @@ void SceneOpenGL::Window::paintDecoration(const QPixmap* decoration, TextureType
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::paintShadow(WindowQuadType type, const QRegion ®ion, const WindowPaintData &data)
|
void SceneOpenGL::Window::paintShadow(const QRegion ®ion, const WindowPaintData &data)
|
||||||
{
|
{
|
||||||
WindowQuadList quads = data.quads.select(type);
|
WindowQuadList quads = data.quads.select(WindowQuadShadowTopLeft);
|
||||||
Texture *texture = static_cast<SceneOpenGLShadow*>(m_shadow)->textureForQuadType(type);
|
quads.append(data.quads.select(WindowQuadShadowTop));
|
||||||
|
quads.append(data.quads.select(WindowQuadShadowTopRight));
|
||||||
|
quads.append(data.quads.select(WindowQuadShadowRight));
|
||||||
|
quads.append(data.quads.select(WindowQuadShadowBottomRight));
|
||||||
|
quads.append(data.quads.select(WindowQuadShadowBottom));
|
||||||
|
quads.append(data.quads.select(WindowQuadShadowBottomLeft));
|
||||||
|
quads.append(data.quads.select(WindowQuadShadowLeft));
|
||||||
|
GLTexture *texture = static_cast<SceneOpenGLShadow*>(m_shadow)->shadowTexture();
|
||||||
if (!texture) {
|
if (!texture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -744,7 +744,7 @@ void SceneOpenGL::Window::makeDecorationArrays(const WindowQuadList& quads, cons
|
||||||
GLVertexBuffer::streamingBuffer()->setData(quads.count() * 6, 2, vertices.data(), texcoords.data());
|
GLVertexBuffer::streamingBuffer()->setData(quads.count() * 6, 2, vertices.data(), texcoords.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::renderQuads(int, const QRegion& region, const WindowQuadList& quads, Texture *tex, bool normalized)
|
void SceneOpenGL::Window::renderQuads(int, const QRegion& region, const WindowQuadList& quads, GLTexture *tex, bool normalized)
|
||||||
{
|
{
|
||||||
if (quads.isEmpty())
|
if (quads.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
@ -762,7 +762,7 @@ void SceneOpenGL::Window::renderQuads(int, const QRegion& region, const WindowQu
|
||||||
size.setHeight(1.0);
|
size.setHeight(1.0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
quads.makeArrays(&vertices, &texcoords, size, tex->getYInverted());
|
quads.makeArrays(&vertices, &texcoords, size, tex->isYInverted());
|
||||||
GLVertexBuffer::streamingBuffer()->setData(quads.count() * 6, 2, vertices, texcoords);
|
GLVertexBuffer::streamingBuffer()->setData(quads.count() * 6, 2, vertices, texcoords);
|
||||||
GLVertexBuffer::streamingBuffer()->render(region, GL_TRIANGLES);
|
GLVertexBuffer::streamingBuffer()->render(region, GL_TRIANGLES);
|
||||||
delete[] vertices;
|
delete[] vertices;
|
||||||
|
@ -798,7 +798,7 @@ void SceneOpenGL::Window::prepareStates(TextureType type, double opacity, double
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::prepareStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, Texture *texture)
|
void SceneOpenGL::Window::prepareStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, GLTexture *texture)
|
||||||
{
|
{
|
||||||
if (shader) {
|
if (shader) {
|
||||||
prepareShaderRenderStates(type, opacity, brightness, saturation, shader);
|
prepareShaderRenderStates(type, opacity, brightness, saturation, shader);
|
||||||
|
@ -835,7 +835,7 @@ void SceneOpenGL::Window::prepareShaderRenderStates(TextureType type, double opa
|
||||||
shader->setUniform(GLShader::AlphaToOne, opaque ? 1 : 0);
|
shader->setUniform(GLShader::AlphaToOne, opaque ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::prepareRenderStates(TextureType type, double opacity, double brightness, double saturation, Texture *tex)
|
void SceneOpenGL::Window::prepareRenderStates(TextureType type, double opacity, double brightness, double saturation, GLTexture *tex)
|
||||||
{
|
{
|
||||||
#ifdef KWIN_HAVE_OPENGLES
|
#ifdef KWIN_HAVE_OPENGLES
|
||||||
Q_UNUSED(type)
|
Q_UNUSED(type)
|
||||||
|
@ -1000,7 +1000,7 @@ void SceneOpenGL::Window::restoreStates(TextureType type, double opacity, double
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::restoreStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, Texture *texture)
|
void SceneOpenGL::Window::restoreStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, GLTexture *texture)
|
||||||
{
|
{
|
||||||
if (shader) {
|
if (shader) {
|
||||||
restoreShaderRenderStates(type, opacity, brightness, saturation, shader);
|
restoreShaderRenderStates(type, opacity, brightness, saturation, shader);
|
||||||
|
@ -1026,7 +1026,7 @@ void SceneOpenGL::Window::restoreShaderRenderStates(TextureType type, double opa
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneOpenGL::Window::restoreRenderStates(TextureType type, double opacity, double brightness, double saturation, Texture *tex)
|
void SceneOpenGL::Window::restoreRenderStates(TextureType type, double opacity, double brightness, double saturation, GLTexture *tex)
|
||||||
{
|
{
|
||||||
Q_UNUSED(type)
|
Q_UNUSED(type)
|
||||||
#ifdef KWIN_HAVE_OPENGLES
|
#ifdef KWIN_HAVE_OPENGLES
|
||||||
|
@ -1535,71 +1535,169 @@ void SceneOpenGL::EffectFrame::cleanup()
|
||||||
//****************************************
|
//****************************************
|
||||||
SceneOpenGLShadow::SceneOpenGLShadow(Toplevel *toplevel)
|
SceneOpenGLShadow::SceneOpenGLShadow(Toplevel *toplevel)
|
||||||
: Shadow(toplevel)
|
: Shadow(toplevel)
|
||||||
|
, m_texture(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneOpenGLShadow::~SceneOpenGLShadow()
|
SceneOpenGLShadow::~SceneOpenGLShadow()
|
||||||
{
|
{
|
||||||
for (int i=0; i<ShadowElementsCount; ++i) {
|
delete m_texture;
|
||||||
m_shadowTextures[i].discard();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SceneOpenGL::Texture *SceneOpenGLShadow::textureForQuadType(WindowQuadType type)
|
void SceneOpenGLShadow::buildQuads()
|
||||||
{
|
{
|
||||||
SceneOpenGL::Texture *texture = NULL;
|
// prepare window quads
|
||||||
QPixmap pixmap;
|
WindowQuadList quads = shadowQuads();
|
||||||
switch (type) {
|
quads.clear();
|
||||||
case WindowQuadShadowTop:
|
const QRectF topRect(QPoint(0, 0), shadowPixmap(ShadowElementTop).size());
|
||||||
texture = &m_shadowTextures[ShadowElementTop];
|
const QRectF topRightRect(QPoint(0, 0), shadowPixmap(ShadowElementTopRight).size());
|
||||||
pixmap = shadowPixmap(ShadowElementTop);
|
const QRectF rightRect(QPoint(0, 0), shadowPixmap(ShadowElementRight).size());
|
||||||
break;
|
const QRectF bottomRightRect(QPoint(0, 0), shadowPixmap(ShadowElementBottomRight).size());
|
||||||
case WindowQuadShadowTopRight:
|
const QRectF bottomRect(QPoint(0, 0), shadowPixmap(ShadowElementBottom).size());
|
||||||
texture = &m_shadowTextures[ShadowElementTopRight];
|
const QRectF bottomLeftRect(QPoint(0, 0), shadowPixmap(ShadowElementBottomLeft).size());
|
||||||
pixmap = shadowPixmap(ShadowElementTopRight);
|
const QRectF leftRect(QPoint(0, 0), shadowPixmap(ShadowElementLeft).size());
|
||||||
break;
|
const QRectF topLeftRect(QPoint(0, 0), shadowPixmap(ShadowElementTopLeft).size());
|
||||||
case WindowQuadShadowRight:
|
if ((leftRect.width() - leftOffset() > topLevel()->width()) ||
|
||||||
texture = &m_shadowTextures[ShadowElementRight];
|
(rightRect.width() - rightOffset() > topLevel()->width()) ||
|
||||||
pixmap = shadowPixmap(ShadowElementRight);
|
(topRect.height() - topOffset() > topLevel()->height()) ||
|
||||||
break;
|
(bottomRect.height() - bottomOffset() > topLevel()->height())) {
|
||||||
case WindowQuadShadowBottomRight:
|
// if our shadow is bigger than the window, we don't render the shadow
|
||||||
texture = &m_shadowTextures[ShadowElementBottomRight];
|
setShadowRegion(QRegion());
|
||||||
pixmap = shadowPixmap(ShadowElementBottomRight);
|
return;
|
||||||
break;
|
|
||||||
case WindowQuadShadowBottom:
|
|
||||||
texture = &m_shadowTextures[ShadowElementBottom];
|
|
||||||
pixmap = shadowPixmap(ShadowElementBottom);
|
|
||||||
break;
|
|
||||||
case WindowQuadShadowBottomLeft:
|
|
||||||
texture = &m_shadowTextures[ShadowElementBottomLeft];
|
|
||||||
pixmap = shadowPixmap(ShadowElementBottomLeft);
|
|
||||||
break;
|
|
||||||
case WindowQuadShadowLeft:
|
|
||||||
texture = &m_shadowTextures[ShadowElementLeft];
|
|
||||||
pixmap = shadowPixmap(ShadowElementLeft);
|
|
||||||
break;
|
|
||||||
case WindowQuadShadowTopLeft:
|
|
||||||
texture = &m_shadowTextures[ShadowElementTopLeft];
|
|
||||||
pixmap = shadowPixmap(ShadowElementTopLeft);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// nothing
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (texture) {
|
// calculate the width
|
||||||
if (texture->texture() != None) {
|
const qreal cornerWidth = topLeftRect.width() + topRightRect.width() + bottomLeftRect.width() + bottomRightRect.width();
|
||||||
glBindTexture(texture->target(), texture->texture());
|
const qreal leftRightWidth = leftRect.width() + rightRect.width();
|
||||||
} else if (!pixmap.isNull()) {
|
const qreal topBottomWidth = topRect.width() + bottomRect.width();
|
||||||
const bool success = texture->load(pixmap);
|
// calculate the height
|
||||||
if (!success) {
|
const qreal cornerHeight = qMax<int>(topLeftRect.height(), qMax<int>(topRightRect.height(), qMax<int>(bottomLeftRect.height(), bottomRightRect.height())));
|
||||||
kDebug(1212) << "Failed to bind shadow pixmap";
|
const qreal leftRightHeight = qMax<int>(leftRect.height(), rightRect.height());
|
||||||
return NULL;
|
const qreal width = m_texture->width();
|
||||||
}
|
const qreal height = m_texture->height();
|
||||||
} else {
|
qreal tx1, tx2, ty1, ty2;
|
||||||
return NULL;
|
tx1 = tx2 = ty1 = ty2 = 0.0;
|
||||||
}
|
tx2 = topLeftRect.width()/width;
|
||||||
|
ty2 = topLeftRect.height()/height;
|
||||||
|
WindowQuad topLeftQuad(WindowQuadShadowTopLeft);
|
||||||
|
topLeftQuad[ 0 ] = WindowVertex(-leftOffset(), -topOffset(), tx1, ty1);
|
||||||
|
topLeftQuad[ 1 ] = WindowVertex(-leftOffset() + topLeftRect.width(), -topOffset(), tx2, ty1);
|
||||||
|
topLeftQuad[ 2 ] = WindowVertex(-leftOffset() + topLeftRect.width(), -topOffset() + topLeftRect.height(), tx2, ty2);
|
||||||
|
topLeftQuad[ 3 ] = WindowVertex(-leftOffset(), -topOffset() + topLeftRect.height(), tx1, ty2);
|
||||||
|
quads.append(topLeftQuad);
|
||||||
|
tx2 = topRect.width()/width;
|
||||||
|
ty1 = (cornerHeight + leftRightHeight)/height;
|
||||||
|
ty2 = (cornerHeight + leftRightHeight + topRect.height())/height;
|
||||||
|
WindowQuad topQuad(WindowQuadShadowTop);
|
||||||
|
topQuad[ 0 ] = WindowVertex(-leftOffset() + topLeftRect.width(), -topOffset(), tx1, ty1);
|
||||||
|
topQuad[ 1 ] = WindowVertex(topLevel()->width() + rightOffset() - topRightRect.width(), -topOffset(), tx2, ty1);
|
||||||
|
topQuad[ 2 ] = WindowVertex(topLevel()->width() + rightOffset() - topRightRect.width(), -topOffset() + topRect.height(),tx2, ty2);
|
||||||
|
topQuad[ 3 ] = WindowVertex(-leftOffset() + topLeftRect.width(), -topOffset() + topRect.height(), tx1, ty2);
|
||||||
|
quads.append(topQuad);
|
||||||
|
tx1 = topLeftRect.width()/width;
|
||||||
|
tx2 = (topLeftRect.width() + topRightRect.width())/width;
|
||||||
|
ty1 = 0.0;
|
||||||
|
ty2 = topRightRect.height()/height;
|
||||||
|
WindowQuad topRightQuad(WindowQuadShadowTopRight);
|
||||||
|
topRightQuad[ 0 ] = WindowVertex(topLevel()->width() + rightOffset() - topRightRect.width(), -topOffset(), tx1, ty1);
|
||||||
|
topRightQuad[ 1 ] = WindowVertex(topLevel()->width() + rightOffset(), -topOffset(), tx2, ty1);
|
||||||
|
topRightQuad[ 2 ] = WindowVertex(topLevel()->width() + rightOffset(), -topOffset() + topRightRect.height(), tx2, ty2);
|
||||||
|
topRightQuad[ 3 ] = WindowVertex(topLevel()->width() + rightOffset() - topRightRect.width(), -topOffset() + topRightRect.height(), tx1, ty2);
|
||||||
|
quads.append(topRightQuad);
|
||||||
|
tx1 = leftRect.width()/width;
|
||||||
|
tx2 = leftRightWidth/width;
|
||||||
|
ty1 = cornerHeight/height;
|
||||||
|
ty2 = (cornerHeight+rightRect.height())/height;
|
||||||
|
WindowQuad rightQuad(WindowQuadShadowRight);
|
||||||
|
rightQuad[ 0 ] = WindowVertex(topLevel()->width() + rightOffset() - rightRect.width(), -topOffset() + topRightRect.height(), tx1, ty1);
|
||||||
|
rightQuad[ 1 ] = WindowVertex(topLevel()->width() + rightOffset(), -topOffset() + topRightRect.height(), tx2, ty1);
|
||||||
|
rightQuad[ 2 ] = WindowVertex(topLevel()->width() + rightOffset(), topLevel()->height() + bottomOffset() - bottomRightRect.height(), tx2, ty2);
|
||||||
|
rightQuad[ 3 ] = WindowVertex(topLevel()->width() + rightOffset() - rightRect.width(), topLevel()->height() + bottomOffset() - bottomRightRect.height(), tx1, ty2);
|
||||||
|
quads.append(rightQuad);
|
||||||
|
tx1 = (topLeftRect.width() + topRightRect.width() + bottomLeftRect.width())/width;
|
||||||
|
tx2 = cornerWidth/width;
|
||||||
|
ty1 = 0.0;
|
||||||
|
ty2 = bottomRightRect.height()/height;
|
||||||
|
WindowQuad bottomRightQuad(WindowQuadShadowBottomRight);
|
||||||
|
bottomRightQuad[ 0 ] = WindowVertex(topLevel()->width() + rightOffset() - bottomRightRect.width(), topLevel()->height() + bottomOffset() - bottomRightRect.height(), tx1, ty1);
|
||||||
|
bottomRightQuad[ 1 ] = WindowVertex(topLevel()->width() + rightOffset(), topLevel()->height() + bottomOffset() - bottomRightRect.height(), tx2, ty1);
|
||||||
|
bottomRightQuad[ 2 ] = WindowVertex(topLevel()->width() + rightOffset(), topLevel()->height() + bottomOffset(), tx2, ty2);
|
||||||
|
bottomRightQuad[ 3 ] = WindowVertex(topLevel()->width() + rightOffset() - bottomRightRect.width(), topLevel()->height() + bottomOffset(), tx1, ty2);
|
||||||
|
quads.append(bottomRightQuad);
|
||||||
|
tx1 = topRect.width()/width;
|
||||||
|
tx2 = topBottomWidth/width;
|
||||||
|
ty1 = (cornerHeight + leftRightHeight)/height;
|
||||||
|
ty2 = (cornerHeight + leftRightHeight + bottomRect.height())/height;
|
||||||
|
WindowQuad bottomQuad(WindowQuadShadowBottom);
|
||||||
|
bottomQuad[ 0 ] = WindowVertex(-leftOffset() + bottomLeftRect.width(), topLevel()->height() + bottomOffset() - bottomRect.height(), tx1, ty1);
|
||||||
|
bottomQuad[ 1 ] = WindowVertex(topLevel()->width() + rightOffset() - bottomRightRect.width(), topLevel()->height() + bottomOffset() - bottomRect.height(), tx2, ty1);
|
||||||
|
bottomQuad[ 2 ] = WindowVertex(topLevel()->width() + rightOffset() - bottomRightRect.width(), topLevel()->height() + bottomOffset(), tx2, ty2);
|
||||||
|
bottomQuad[ 3 ] = WindowVertex(-leftOffset() + bottomLeftRect.width(), topLevel()->height() + bottomOffset(), tx1, ty2);
|
||||||
|
quads.append(bottomQuad);
|
||||||
|
tx1 = (topLeftRect.width() + topRightRect.width())/width;
|
||||||
|
tx2 = (topLeftRect.width() + topRightRect.width() + bottomLeftRect.width())/width;
|
||||||
|
ty1 = 0.0;
|
||||||
|
ty2 = bottomLeftRect.height()/height;
|
||||||
|
WindowQuad bottomLeftQuad(WindowQuadShadowBottomLeft);
|
||||||
|
bottomLeftQuad[ 0 ] = WindowVertex(-leftOffset(), topLevel()->height() + bottomOffset() - bottomLeftRect.height(), tx1, ty1);
|
||||||
|
bottomLeftQuad[ 1 ] = WindowVertex(-leftOffset() + bottomLeftRect.width(), topLevel()->height() + bottomOffset() - bottomLeftRect.height(), tx2, ty1);
|
||||||
|
bottomLeftQuad[ 2 ] = WindowVertex(-leftOffset() + bottomLeftRect.width(), topLevel()->height() + bottomOffset(), tx2, ty2);
|
||||||
|
bottomLeftQuad[ 3 ] = WindowVertex(-leftOffset(), topLevel()->height() + bottomOffset(), tx1, ty2);
|
||||||
|
quads.append(bottomLeftQuad);
|
||||||
|
tx1 = 0.0;
|
||||||
|
tx2 = leftRect.width()/width;
|
||||||
|
ty1 = cornerHeight/height;
|
||||||
|
ty2 = (cornerHeight+leftRect.height())/height;
|
||||||
|
WindowQuad leftQuad(WindowQuadShadowLeft);
|
||||||
|
leftQuad[ 0 ] = WindowVertex(-leftOffset(), -topOffset() + topLeftRect.height(), tx1, ty1);
|
||||||
|
leftQuad[ 1 ] = WindowVertex(-leftOffset() + leftRect.width(), -topOffset() + topLeftRect.height(), tx2, ty1);
|
||||||
|
leftQuad[ 2 ] = WindowVertex(-leftOffset() + leftRect.width(), topLevel()->height() + bottomOffset() - bottomLeftRect.height(), tx2, ty2);
|
||||||
|
leftQuad[ 3 ] = WindowVertex(-leftOffset(), topLevel()->height() + bottomOffset() - bottomLeftRect.height(), tx1, ty2);
|
||||||
|
quads.append(leftQuad);
|
||||||
|
m_shadowQuads = quads;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SceneOpenGLShadow::prepareBackend()
|
||||||
|
{
|
||||||
|
const QRect topRect(QPoint(0, 0), shadowPixmap(ShadowElementTop).size());
|
||||||
|
const QRect topRightRect(QPoint(0, 0), shadowPixmap(ShadowElementTopRight).size());
|
||||||
|
const QRect rightRect(QPoint(0, 0), shadowPixmap(ShadowElementRight).size());
|
||||||
|
const QRect bottomRightRect(QPoint(0, 0), shadowPixmap(ShadowElementBottomRight).size());
|
||||||
|
const QRect bottomRect(QPoint(0, 0), shadowPixmap(ShadowElementBottom).size());
|
||||||
|
const QRect bottomLeftRect(QPoint(0, 0), shadowPixmap(ShadowElementBottomLeft).size());
|
||||||
|
const QRect leftRect(QPoint(0, 0), shadowPixmap(ShadowElementLeft).size());
|
||||||
|
const QRect topLeftRect(QPoint(0, 0), shadowPixmap(ShadowElementTopLeft).size());
|
||||||
|
// calculate the width
|
||||||
|
const int cornerWidth = topLeftRect.width() + topRightRect.width() + bottomLeftRect.width() + bottomRightRect.width();
|
||||||
|
const int leftRightWidth = leftRect.width() + rightRect.width();
|
||||||
|
const int topBottomWidth = topRect.width() + bottomRect.width();
|
||||||
|
const int width = qMax<int>(cornerWidth, qMax<int>(leftRightWidth, topBottomWidth));
|
||||||
|
// calculate the height
|
||||||
|
const int cornerHeight = qMax<int>(topLeftRect.height(), qMax<int>(topRightRect.height(), qMax<int>(bottomLeftRect.height(), bottomRightRect.height())));
|
||||||
|
const int leftRightHeight = qMax<int>(leftRect.height(), rightRect.height());
|
||||||
|
const int topBottomHeight = qMax<int>(topRect.height(), bottomRect.height());
|
||||||
|
const int height = cornerHeight + leftRightHeight + topBottomHeight;
|
||||||
|
|
||||||
|
QImage image(width, height, QImage::Format_ARGB32);
|
||||||
|
image.fill(Qt::transparent);
|
||||||
|
QPainter p;
|
||||||
|
p.begin(&image);
|
||||||
|
p.drawPixmap(0, 0, shadowPixmap(ShadowElementTopLeft));
|
||||||
|
p.drawPixmap(topLeftRect.width(), 0, shadowPixmap(ShadowElementTopRight));
|
||||||
|
p.drawPixmap(topLeftRect.width() + topRightRect.width(), 0, shadowPixmap(ShadowElementBottomLeft));
|
||||||
|
p.drawPixmap(topLeftRect.width() + topRightRect.width() + bottomLeftRect.width(), 0, shadowPixmap(ShadowElementBottomRight));
|
||||||
|
p.drawPixmap(0, cornerHeight, shadowPixmap(ShadowElementLeft));
|
||||||
|
p.drawPixmap(leftRect.width(), cornerHeight, shadowPixmap(ShadowElementRight));
|
||||||
|
p.drawPixmap(0, cornerHeight + leftRightHeight, shadowPixmap(ShadowElementTop));
|
||||||
|
p.drawPixmap(topRect.width(), cornerHeight + leftRightHeight, shadowPixmap(ShadowElementBottom));
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
if (m_texture) {
|
||||||
|
delete m_texture;
|
||||||
|
m_texture = NULL;
|
||||||
}
|
}
|
||||||
return texture;
|
|
||||||
|
m_texture = new GLTexture(image);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -167,16 +167,16 @@ protected:
|
||||||
|
|
||||||
QMatrix4x4 transformation(int mask, const WindowPaintData &data) const;
|
QMatrix4x4 transformation(int mask, const WindowPaintData &data) const;
|
||||||
void paintDecoration(const QPixmap* decoration, TextureType decorationType, const QRegion& region, const QRect& rect, const WindowPaintData& data, const WindowQuadList& quads, bool updateDeco);
|
void paintDecoration(const QPixmap* decoration, TextureType decorationType, const QRegion& region, const QRect& rect, const WindowPaintData& data, const WindowQuadList& quads, bool updateDeco);
|
||||||
void paintShadow(WindowQuadType type, const QRegion ®ion, const WindowPaintData &data);
|
void paintShadow(const QRegion ®ion, const WindowPaintData &data);
|
||||||
void makeDecorationArrays(const WindowQuadList& quads, const QRect &rect, Texture *tex) const;
|
void makeDecorationArrays(const WindowQuadList& quads, const QRect &rect, Texture *tex) const;
|
||||||
void renderQuads(int, const QRegion& region, const WindowQuadList& quads, Texture* tex, bool normalized = false);
|
void renderQuads(int, const QRegion& region, const WindowQuadList& quads, GLTexture* tex, bool normalized = false);
|
||||||
void prepareStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
void prepareStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
||||||
void prepareStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, Texture *texture);
|
void prepareStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, GLTexture *texture);
|
||||||
void prepareRenderStates(TextureType type, double opacity, double brightness, double saturation, Texture *tex);
|
void prepareRenderStates(TextureType type, double opacity, double brightness, double saturation, GLTexture *tex);
|
||||||
void prepareShaderRenderStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
void prepareShaderRenderStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
||||||
void restoreStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
void restoreStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
||||||
void restoreStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, Texture *texture);
|
void restoreStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, GLTexture *texture);
|
||||||
void restoreRenderStates(TextureType type, double opacity, double brightness, double saturation, Texture *tex);
|
void restoreRenderStates(TextureType type, double opacity, double brightness, double saturation, GLTexture *tex);
|
||||||
void restoreShaderRenderStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
void restoreShaderRenderStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -237,16 +237,14 @@ public:
|
||||||
SceneOpenGLShadow(Toplevel *toplevel);
|
SceneOpenGLShadow(Toplevel *toplevel);
|
||||||
virtual ~SceneOpenGLShadow();
|
virtual ~SceneOpenGLShadow();
|
||||||
|
|
||||||
/**
|
GLTexture *shadowTexture() {
|
||||||
* Returns the Texture for a specific ShadowQuad. The method takes care of performing
|
return m_texture;
|
||||||
* the Texture from Pixmap operation. The calling method can use the returned Texture
|
}
|
||||||
* directly.
|
protected:
|
||||||
* In error case the method returns @c NULL.
|
virtual void buildQuads();
|
||||||
* @return OpenGL Texture for the Shadow Quad. May be @c NULL.
|
virtual bool prepareBackend();
|
||||||
**/
|
|
||||||
SceneOpenGL::Texture *textureForQuadType(WindowQuadType type);
|
|
||||||
private:
|
private:
|
||||||
SceneOpenGL::Texture m_shadowTextures[ShadowElementsCount];
|
GLTexture *m_texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -162,6 +162,9 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void buildQuads();
|
virtual void buildQuads();
|
||||||
|
virtual bool prepareBackend() {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QPixmap m_resizedElements[ShadowElementsCount];
|
QPixmap m_resizedElements[ShadowElementsCount];
|
||||||
|
|
|
@ -110,6 +110,9 @@ bool Shadow::init(const QVector< long > &data)
|
||||||
m_bottomOffset = data[ShadowElementsCount+2];
|
m_bottomOffset = data[ShadowElementsCount+2];
|
||||||
m_leftOffset = data[ShadowElementsCount+3];
|
m_leftOffset = data[ShadowElementsCount+3];
|
||||||
updateShadowRegion();
|
updateShadowRegion();
|
||||||
|
if (!prepareBackend()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
buildQuads();
|
buildQuads();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
15
shadow.h
15
shadow.h
|
@ -23,6 +23,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtGui/QPixmap>
|
#include <QtGui/QPixmap>
|
||||||
#include <kwineffects.h>
|
#include <kwineffects.h>
|
||||||
|
#include <qvarlengtharray.h>
|
||||||
|
|
||||||
namespace KWin {
|
namespace KWin {
|
||||||
|
|
||||||
|
@ -58,7 +59,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* @return Cached Shadow Quads
|
* @return Cached Shadow Quads
|
||||||
**/
|
**/
|
||||||
const WindowQuadList &shadowQuads() {
|
const WindowQuadList &shadowQuads() const {
|
||||||
|
return m_shadowQuads;
|
||||||
|
};
|
||||||
|
WindowQuadList &shadowQuads() {
|
||||||
return m_shadowQuads;
|
return m_shadowQuads;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,6 +129,14 @@ protected:
|
||||||
};
|
};
|
||||||
virtual void buildQuads();
|
virtual void buildQuads();
|
||||||
void updateShadowRegion();
|
void updateShadowRegion();
|
||||||
|
Toplevel *topLevel() {
|
||||||
|
return m_topLevel;
|
||||||
|
};
|
||||||
|
void setShadowRegion(const QRegion ®ion) {
|
||||||
|
m_shadowRegion = region;
|
||||||
|
};
|
||||||
|
virtual bool prepareBackend() = 0;
|
||||||
|
WindowQuadList m_shadowQuads;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static QVector<long> readX11ShadowProperty(WId id);
|
static QVector<long> readX11ShadowProperty(WId id);
|
||||||
|
@ -139,7 +151,6 @@ private:
|
||||||
int m_leftOffset;
|
int m_leftOffset;
|
||||||
// caches
|
// caches
|
||||||
QRegion m_shadowRegion;
|
QRegion m_shadowRegion;
|
||||||
WindowQuadList m_shadowQuads;
|
|
||||||
QSize m_cachedSize;
|
QSize m_cachedSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue