void ShowFpsEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) { effects->paintScreen(mask, region, data); int fps = 0; for (int i = 0; i < MAX_FPS; ++i) if (abs(t.minute() * 60000 + t.second() * 1000 + t.msec() - frames[ i ]) < 1000) ++fps; // count all frames in the last second if (fps > MAX_TIME) fps = MAX_TIME; // keep it the same height if (effects->isOpenGLCompositing()) { paintGL(fps); glFinish(); // make sure all rendering is done } #ifdef KWIN_HAVE_XRENDER_COMPOSITING if (effects->compositingType() == XRenderCompositing) { paintXrender(fps); xcb_flush(xcbConnection()); // make sure all rendering is done } #endif if (effects->compositingType() == QPainterCompositing) { paintQPainter(fps); } m_noBenchmark->render(infiniteRegion(), 1.0, alpha); }
void CubeSlideEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) { if (!slideRotations.empty()) { glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); paintSlideCube(mask, region, data); glCullFace(GL_BACK); paintSlideCube(mask, region, data); glDisable(GL_CULL_FACE); if (dontSlidePanels) { foreach (EffectWindow * w, panels) { WindowPaintData wData(w); effects->paintWindow(w, 0, infiniteRegion(), wData); } }
foreach (EffectWindow * w, stickyWindows) { WindowPaintData wData(w); effects->paintWindow(w, 0, infiniteRegion(), wData); }
void LanczosFilter::performPaint(EffectWindowImpl* w, int mask, QRegion region, WindowPaintData& data) { if (effects->compositingType() == KWin::OpenGLCompositing && (data.xScale() < 0.9 || data.yScale() < 0.9) && KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) { if (!m_inited) init(); const QRect screenRect = Workspace::self()->clientArea(ScreenArea, w->screen(), w->desktop()); // window geometry may not be bigger than screen geometry to fit into the FBO if (m_shader && w->width() <= screenRect.width() && w->height() <= screenRect.height()) { double left = 0; double top = 0; double right = w->width(); double bottom = w->height(); foreach (const WindowQuad & quad, data.quads) { // we need this loop to include the decoration padding left = qMin(left, quad.left()); top = qMin(top, quad.top()); right = qMax(right, quad.right()); bottom = qMax(bottom, quad.bottom()); } double width = right - left; double height = bottom - top; if (width > screenRect.width() || height > screenRect.height()) { // window with padding does not fit into the framebuffer // so cut of the shadow left = 0; top = 0; width = w->width(); height = w->height(); } int tx = data.xTranslation() + w->x() + left * data.xScale(); int ty = data.yTranslation() + w->y() + top * data.yScale(); int tw = width * data.xScale(); int th = height * data.yScale(); const QRect textureRect(tx, ty, tw, th); const bool hardwareClipping = !(QRegion(textureRect)-region).isEmpty(); int sw = width; int sh = height; GLTexture *cachedTexture = static_cast< GLTexture*>(w->data(LanczosCacheRole).value<void*>()); if (cachedTexture) { if (cachedTexture->width() == tw && cachedTexture->height() == th) { cachedTexture->bind(); if (hardwareClipping) { glEnable(GL_SCISSOR_TEST); } if (ShaderManager::instance()->isValid()) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); const qreal rgb = data.brightness() * data.opacity(); const qreal a = data.opacity(); GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader); shader->setUniform(GLShader::Offset, QVector2D(0, 0)); shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a)); shader->setUniform(GLShader::Saturation, data.saturation()); shader->setUniform(GLShader::AlphaToOne, 0); cachedTexture->render(region, textureRect, hardwareClipping); ShaderManager::instance()->popShader(); glDisable(GL_BLEND); } else { prepareRenderStates(cachedTexture, data.opacity(), data.brightness(), data.saturation()); cachedTexture->render(region, textureRect, hardwareClipping); restoreRenderStates(cachedTexture, data.opacity(), data.brightness(), data.saturation()); } if (hardwareClipping) { glDisable(GL_SCISSOR_TEST); } cachedTexture->unbind(); m_timer.start(5000, this); return; } else { // offscreen texture not matching - delete delete cachedTexture; cachedTexture = 0; w->setData(LanczosCacheRole, QVariant()); } } WindowPaintData thumbData = data; thumbData.setXScale(1.0); thumbData.setYScale(1.0); thumbData.setXTranslation(-w->x() - left); thumbData.setYTranslation(-w->y() - top); thumbData.setBrightness(1.0); thumbData.setOpacity(1.0); thumbData.setSaturation(1.0); // Bind the offscreen FBO and draw the window on it unscaled updateOffscreenSurfaces(); GLRenderTarget::pushRenderTarget(m_offscreenTarget); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); w->sceneWindow()->performPaint(mask, infiniteRegion(), thumbData); // Create a scratch texture and copy the rendered window into it GLTexture tex(sw, sh); tex.setFilter(GL_LINEAR); tex.setWrapMode(GL_CLAMP_TO_EDGE); tex.bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, sw, sh); // Set up the shader for horizontal scaling float dx = sw / float(tw); int kernelSize; m_shader->createKernel(dx, &kernelSize); m_shader->createOffsets(kernelSize, sw, Qt::Horizontal); m_shader->bind(); m_shader->setUniforms(); // Draw the window back into the FBO, this time scaled horizontally glClear(GL_COLOR_BUFFER_BIT); QVector<float> verts; QVector<float> texCoords; verts.reserve(12); texCoords.reserve(12); texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right texCoords << 0.0 << 0.0; verts << 0.0 << 0.0; // Top left texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left texCoords << 0.0 << 1.0; verts << 0.0 << sh; // Bottom left texCoords << 1.0 << 1.0; verts << tw << sh; // Bottom right texCoords << 1.0 << 0.0; verts << tw << 0.0; // Top right GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); vbo->reset(); vbo->setData(6, 2, verts.constData(), texCoords.constData()); vbo->render(GL_TRIANGLES); // At this point we don't need the scratch texture anymore tex.unbind(); tex.discard(); // create scratch texture for second rendering pass GLTexture tex2(tw, sh); tex2.setFilter(GL_LINEAR); tex2.setWrapMode(GL_CLAMP_TO_EDGE); tex2.bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - sh, tw, sh); // Set up the shader for vertical scaling float dy = sh / float(th); m_shader->createKernel(dy, &kernelSize); m_shader->createOffsets(kernelSize, m_offscreenTex->height(), Qt::Vertical); m_shader->setUniforms(); // Now draw the horizontally scaled window in the FBO at the right // coordinates on the screen, while scaling it vertically and blending it. glClear(GL_COLOR_BUFFER_BIT); verts.clear(); verts << tw << 0.0; // Top right verts << 0.0 << 0.0; // Top left verts << 0.0 << th; // Bottom left verts << 0.0 << th; // Bottom left verts << tw << th; // Bottom right verts << tw << 0.0; // Top right vbo->setData(6, 2, verts.constData(), texCoords.constData()); vbo->render(GL_TRIANGLES); tex2.unbind(); tex2.discard(); m_shader->unbind(); // create cache texture GLTexture *cache = new GLTexture(tw, th); cache->setFilter(GL_LINEAR); cache->setWrapMode(GL_CLAMP_TO_EDGE); cache->bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, m_offscreenTex->height() - th, tw, th); GLRenderTarget::popRenderTarget(); if (hardwareClipping) { glEnable(GL_SCISSOR_TEST); } if (ShaderManager::instance()->isValid()) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); const qreal rgb = data.brightness() * data.opacity(); const qreal a = data.opacity(); GLShader *shader = ShaderManager::instance()->pushShader(ShaderManager::SimpleShader); shader->setUniform(GLShader::Offset, QVector2D(0, 0)); shader->setUniform(GLShader::ModulationConstant, QVector4D(rgb, rgb, rgb, a)); shader->setUniform(GLShader::Saturation, data.saturation()); shader->setUniform(GLShader::AlphaToOne, 0); cache->render(region, textureRect, hardwareClipping); ShaderManager::instance()->popShader(); glDisable(GL_BLEND); } else { prepareRenderStates(cache, data.opacity(), data.brightness(), data.saturation()); cache->render(region, textureRect, hardwareClipping); restoreRenderStates(cache, data.opacity(), data.brightness(), data.saturation()); } if (hardwareClipping) { glDisable(GL_SCISSOR_TEST); } cache->unbind(); w->setData(LanczosCacheRole, QVariant::fromValue(static_cast<void*>(cache))); // Delete the offscreen surface after 5 seconds m_timer.start(5000, this); return; } } // if ( effects->compositingType() == KWin::OpenGLCompositing )