Render Shadow with only one GL texture
Copies the shadow parts into one image and creates a GLTexture from the image, so that we can render the complete shadow with just one texture and one painting pass. Should remove most of the overhead involved when rendering the new Shadows. As a side effect this should fix missing shadows with non-NPOT GPUs and a rendering glitch reported with NVIDIA. REVIEW: 101742
This commit is contained in:
parent
a1b110634f
commit
b837a3fca1
7 changed files with 211 additions and 89 deletions
|
@ -695,6 +695,11 @@ QImage GLTexture::convertToGLFormat(const QImage& img) const
|
|||
return res;
|
||||
}
|
||||
|
||||
bool GLTexture::isYInverted() const
|
||||
{
|
||||
return y_inverted;
|
||||
}
|
||||
|
||||
//****************************************
|
||||
// GLShader
|
||||
//****************************************
|
||||
|
|
|
@ -150,6 +150,10 @@ public:
|
|||
int height() const {
|
||||
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 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
|
||||
if (m_shadow) {
|
||||
paintShadow(WindowQuadShadowTop, 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);
|
||||
paintShadow(region, data);
|
||||
}
|
||||
// decorations
|
||||
Client *client = dynamic_cast<Client*>(toplevel);
|
||||
|
@ -659,10 +652,17 @@ void SceneOpenGL::Window::paintDecoration(const QPixmap* decoration, TextureType
|
|||
#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);
|
||||
Texture *texture = static_cast<SceneOpenGLShadow*>(m_shadow)->textureForQuadType(type);
|
||||
WindowQuadList quads = data.quads.select(WindowQuadShadowTopLeft);
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
@ -744,7 +744,7 @@ void SceneOpenGL::Window::makeDecorationArrays(const WindowQuadList& quads, cons
|
|||
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())
|
||||
return;
|
||||
|
@ -762,7 +762,7 @@ void SceneOpenGL::Window::renderQuads(int, const QRegion& region, const WindowQu
|
|||
size.setHeight(1.0);
|
||||
}
|
||||
#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()->render(region, GL_TRIANGLES);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
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) {
|
||||
restoreShaderRenderStates(type, opacity, brightness, saturation, shader);
|
||||
|
@ -1026,7 +1026,7 @@ void SceneOpenGL::Window::restoreShaderRenderStates(TextureType type, double opa
|
|||
#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)
|
||||
#ifdef KWIN_HAVE_OPENGLES
|
||||
|
@ -1535,71 +1535,169 @@ void SceneOpenGL::EffectFrame::cleanup()
|
|||
//****************************************
|
||||
SceneOpenGLShadow::SceneOpenGLShadow(Toplevel *toplevel)
|
||||
: Shadow(toplevel)
|
||||
, m_texture(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
SceneOpenGLShadow::~SceneOpenGLShadow()
|
||||
{
|
||||
for (int i=0; i<ShadowElementsCount; ++i) {
|
||||
m_shadowTextures[i].discard();
|
||||
}
|
||||
delete m_texture;
|
||||
}
|
||||
|
||||
SceneOpenGL::Texture *SceneOpenGLShadow::textureForQuadType(WindowQuadType type)
|
||||
void SceneOpenGLShadow::buildQuads()
|
||||
{
|
||||
SceneOpenGL::Texture *texture = NULL;
|
||||
QPixmap pixmap;
|
||||
switch (type) {
|
||||
case WindowQuadShadowTop:
|
||||
texture = &m_shadowTextures[ShadowElementTop];
|
||||
pixmap = shadowPixmap(ShadowElementTop);
|
||||
break;
|
||||
case WindowQuadShadowTopRight:
|
||||
texture = &m_shadowTextures[ShadowElementTopRight];
|
||||
pixmap = shadowPixmap(ShadowElementTopRight);
|
||||
break;
|
||||
case WindowQuadShadowRight:
|
||||
texture = &m_shadowTextures[ShadowElementRight];
|
||||
pixmap = shadowPixmap(ShadowElementRight);
|
||||
break;
|
||||
case WindowQuadShadowBottomRight:
|
||||
texture = &m_shadowTextures[ShadowElementBottomRight];
|
||||
pixmap = shadowPixmap(ShadowElementBottomRight);
|
||||
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;
|
||||
// prepare window quads
|
||||
WindowQuadList quads = shadowQuads();
|
||||
quads.clear();
|
||||
const QRectF topRect(QPoint(0, 0), shadowPixmap(ShadowElementTop).size());
|
||||
const QRectF topRightRect(QPoint(0, 0), shadowPixmap(ShadowElementTopRight).size());
|
||||
const QRectF rightRect(QPoint(0, 0), shadowPixmap(ShadowElementRight).size());
|
||||
const QRectF bottomRightRect(QPoint(0, 0), shadowPixmap(ShadowElementBottomRight).size());
|
||||
const QRectF bottomRect(QPoint(0, 0), shadowPixmap(ShadowElementBottom).size());
|
||||
const QRectF bottomLeftRect(QPoint(0, 0), shadowPixmap(ShadowElementBottomLeft).size());
|
||||
const QRectF leftRect(QPoint(0, 0), shadowPixmap(ShadowElementLeft).size());
|
||||
const QRectF topLeftRect(QPoint(0, 0), shadowPixmap(ShadowElementTopLeft).size());
|
||||
if ((leftRect.width() - leftOffset() > topLevel()->width()) ||
|
||||
(rightRect.width() - rightOffset() > topLevel()->width()) ||
|
||||
(topRect.height() - topOffset() > topLevel()->height()) ||
|
||||
(bottomRect.height() - bottomOffset() > topLevel()->height())) {
|
||||
// if our shadow is bigger than the window, we don't render the shadow
|
||||
setShadowRegion(QRegion());
|
||||
return;
|
||||
}
|
||||
if (texture) {
|
||||
if (texture->texture() != None) {
|
||||
glBindTexture(texture->target(), texture->texture());
|
||||
} else if (!pixmap.isNull()) {
|
||||
const bool success = texture->load(pixmap);
|
||||
if (!success) {
|
||||
kDebug(1212) << "Failed to bind shadow pixmap";
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
// calculate the width
|
||||
const qreal cornerWidth = topLeftRect.width() + topRightRect.width() + bottomLeftRect.width() + bottomRightRect.width();
|
||||
const qreal leftRightWidth = leftRect.width() + rightRect.width();
|
||||
const qreal topBottomWidth = topRect.width() + bottomRect.width();
|
||||
// calculate the height
|
||||
const qreal cornerHeight = qMax<int>(topLeftRect.height(), qMax<int>(topRightRect.height(), qMax<int>(bottomLeftRect.height(), bottomRightRect.height())));
|
||||
const qreal leftRightHeight = qMax<int>(leftRect.height(), rightRect.height());
|
||||
const qreal width = m_texture->width();
|
||||
const qreal height = m_texture->height();
|
||||
qreal tx1, tx2, ty1, ty2;
|
||||
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
|
||||
|
|
|
@ -167,16 +167,16 @@ protected:
|
|||
|
||||
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 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 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, Texture *texture);
|
||||
void prepareRenderStates(TextureType type, double opacity, double brightness, double saturation, Texture *tex);
|
||||
void prepareStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, GLTexture *texture);
|
||||
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 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 restoreRenderStates(TextureType type, double opacity, double brightness, double saturation, Texture *tex);
|
||||
void restoreStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader, GLTexture *texture);
|
||||
void restoreRenderStates(TextureType type, double opacity, double brightness, double saturation, GLTexture *tex);
|
||||
void restoreShaderRenderStates(TextureType type, double opacity, double brightness, double saturation, GLShader* shader);
|
||||
|
||||
private:
|
||||
|
@ -237,16 +237,14 @@ public:
|
|||
SceneOpenGLShadow(Toplevel *toplevel);
|
||||
virtual ~SceneOpenGLShadow();
|
||||
|
||||
/**
|
||||
* Returns the Texture for a specific ShadowQuad. The method takes care of performing
|
||||
* the Texture from Pixmap operation. The calling method can use the returned Texture
|
||||
* directly.
|
||||
* In error case the method returns @c NULL.
|
||||
* @return OpenGL Texture for the Shadow Quad. May be @c NULL.
|
||||
**/
|
||||
SceneOpenGL::Texture *textureForQuadType(WindowQuadType type);
|
||||
GLTexture *shadowTexture() {
|
||||
return m_texture;
|
||||
}
|
||||
protected:
|
||||
virtual void buildQuads();
|
||||
virtual bool prepareBackend();
|
||||
private:
|
||||
SceneOpenGL::Texture m_shadowTextures[ShadowElementsCount];
|
||||
GLTexture *m_texture;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -165,6 +165,9 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void buildQuads();
|
||||
virtual bool prepareBackend() {
|
||||
return true;
|
||||
};
|
||||
|
||||
private:
|
||||
QPixmap m_resizedElements[ShadowElementsCount];
|
||||
|
|
|
@ -110,6 +110,9 @@ bool Shadow::init(const QVector< long > &data)
|
|||
m_bottomOffset = data[ShadowElementsCount+2];
|
||||
m_leftOffset = data[ShadowElementsCount+3];
|
||||
updateShadowRegion();
|
||||
if (!prepareBackend()) {
|
||||
return false;
|
||||
}
|
||||
buildQuads();
|
||||
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 <QtGui/QPixmap>
|
||||
#include <kwineffects.h>
|
||||
#include <qvarlengtharray.h>
|
||||
|
||||
namespace KWin {
|
||||
|
||||
|
@ -58,7 +59,10 @@ public:
|
|||
/**
|
||||
* @return Cached Shadow Quads
|
||||
**/
|
||||
const WindowQuadList &shadowQuads() {
|
||||
const WindowQuadList &shadowQuads() const {
|
||||
return m_shadowQuads;
|
||||
};
|
||||
WindowQuadList &shadowQuads() {
|
||||
return m_shadowQuads;
|
||||
};
|
||||
|
||||
|
@ -125,6 +129,14 @@ protected:
|
|||
};
|
||||
virtual void buildQuads();
|
||||
void updateShadowRegion();
|
||||
Toplevel *topLevel() {
|
||||
return m_topLevel;
|
||||
};
|
||||
void setShadowRegion(const QRegion ®ion) {
|
||||
m_shadowRegion = region;
|
||||
};
|
||||
virtual bool prepareBackend() = 0;
|
||||
WindowQuadList m_shadowQuads;
|
||||
|
||||
private:
|
||||
static QVector<long> readX11ShadowProperty(WId id);
|
||||
|
@ -139,7 +151,6 @@ private:
|
|||
int m_leftOffset;
|
||||
// caches
|
||||
QRegion m_shadowRegion;
|
||||
WindowQuadList m_shadowQuads;
|
||||
QSize m_cachedSize;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue