From b5279af212c91720c4c38e895c2dbc3cb8b3bd8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Sat, 20 Aug 2011 10:53:36 +0200 Subject: [PATCH] Bring back the magnifier effect Effect uses framebuffer blit to copy the zoomed are in a scaled way into an offscreen texture and render the texture after the rendering. This means instead of two rendering passes we now need only one pass, but require the blit extension. --- effects/CMakeLists.txt | 3 +- effects/configs_builtins.cpp | 5 ---- effects/magnifier/magnifier.cpp | 49 ++++++++++++++++++++++++--------- effects/magnifier/magnifier.h | 7 +++++ 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/effects/CMakeLists.txt b/effects/CMakeLists.txt index 17e3d7bfbd..5734b289fa 100644 --- a/effects/CMakeLists.txt +++ b/effects/CMakeLists.txt @@ -125,8 +125,7 @@ if( NOT KWIN_MOBILE_EFFECTS ) include( glide/CMakeLists.txt ) include( invert/CMakeLists.txt ) include( lookingglass/CMakeLists.txt ) -# Magnifier currently broken due to removed PaintClipper -# include( magnifier/CMakeLists.txt ) + include( magnifier/CMakeLists.txt ) include( mousemark/CMakeLists.txt ) include( sheet/CMakeLists.txt ) include( snaphelper/CMakeLists.txt ) diff --git a/effects/configs_builtins.cpp b/effects/configs_builtins.cpp index 85db0c8010..b291e388ad 100644 --- a/effects/configs_builtins.cpp +++ b/effects/configs_builtins.cpp @@ -45,10 +45,7 @@ along with this program. If not, see . #include "glide/glide_config.h" #include "invert/invert_config.h" #include "lookingglass/lookingglass_config.h" -#if 0 -// Magnifier currently broken due to removed PaintClipper #include "magnifier/magnifier_config.h" -#endif #include "mousemark/mousemark_config.h" #include "trackmouse/trackmouse_config.h" #include "wobblywindows/wobblywindows_config.h" @@ -85,9 +82,7 @@ KWIN_EFFECT_CONFIG_MULTIPLE(builtins, KWIN_EFFECT_CONFIG_SINGLE(glide, GlideEffectConfig) KWIN_EFFECT_CONFIG_SINGLE(invert, InvertEffectConfig) KWIN_EFFECT_CONFIG_SINGLE(lookingglass, LookingGlassEffectConfig) -#if 0 KWIN_EFFECT_CONFIG_SINGLE(magnifier, MagnifierEffectConfig) -#endif KWIN_EFFECT_CONFIG_SINGLE(mousemark, MouseMarkEffectConfig) KWIN_EFFECT_CONFIG_SINGLE(trackmouse, TrackMouseEffectConfig) KWIN_EFFECT_CONFIG_SINGLE(wobblywindows, WobblyWindowsEffectConfig) diff --git a/effects/magnifier/magnifier.cpp b/effects/magnifier/magnifier.cpp index 5fea59c10d..3e216f6736 100644 --- a/effects/magnifier/magnifier.cpp +++ b/effects/magnifier/magnifier.cpp @@ -4,6 +4,7 @@ Copyright (C) 2007 Lubos Lunak Copyright (C) 2007 Christian Nitschkowski +Copyright (C) 2011 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -42,6 +43,8 @@ MagnifierEffect::MagnifierEffect() : zoom(1) , target_zoom(1) , polling(false) + , m_texture(0) + , m_fbo(0) { KActionCollection* actionCollection = new KActionCollection(this); KAction* a; @@ -56,9 +59,15 @@ MagnifierEffect::MagnifierEffect() reconfigure(ReconfigureAll); } +MagnifierEffect::~MagnifierEffect() +{ + delete m_fbo; + delete m_texture; +} + bool MagnifierEffect::supported() { - return effects->compositingType() == OpenGLCompositing; + return effects->compositingType() == OpenGLCompositing && GLRenderTarget::blitSupported(); } void MagnifierEffect::reconfigure(ReconfigureFlags) @@ -86,21 +95,17 @@ void MagnifierEffect::prePaintScreen(ScreenPrePaintData& data, int time) void MagnifierEffect::paintScreen(int mask, QRegion region, ScreenPaintData& data) { - ScreenPaintData data2 = data; effects->paintScreen(mask, region, data); // paint normal screen if (zoom != 1.0) { + // get the right area from the current rendered screen + const QRect area = magnifierArea(); + const QPoint cursor = cursorPos(); + m_fbo->blitFromFramebuffer(QRect(cursor.x() - (double)area.width() / (zoom*2), cursor.y() - (double)area.height() / (zoom*2), + (double)area.width() / zoom, (double)area.height() / zoom)); // paint magnifier - QRect area = magnifierArea(); - PaintClipper::push(area); // don't allow any painting outside of the area - mask |= PAINT_SCREEN_TRANSFORMED; - data2.xScale *= zoom; - data2.yScale *= zoom; - QPoint cursor = cursorPos(); - // set the position so that the cursor is in the same position in the scaled view - data2.xTranslate = - int(cursor.x() * (zoom - 1)); - data2.yTranslate = - int(cursor.y() * (zoom - 1)); - effects->paintScreen(mask, region, data2); - PaintClipper::pop(area); + m_texture->bind(); + m_texture->render(infiniteRegion(), area); + m_texture->unbind(); QVector verts; GLVertexBuffer *vbo = GLVertexBuffer::streamingBuffer(); vbo->reset(); @@ -166,6 +171,11 @@ void MagnifierEffect::zoomIn() polling = true; effects->startMousePolling(); } + if (!m_texture) { + m_texture = new GLTexture(magnifier_size); + m_texture->setYInverted(false); + m_fbo = new GLRenderTarget(m_texture); + } effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH)); } @@ -178,6 +188,10 @@ void MagnifierEffect::zoomOut() polling = false; effects->stopMousePolling(); } + delete m_fbo; + delete m_texture; + m_fbo = NULL; + m_texture = NULL; } effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH)); } @@ -190,12 +204,21 @@ void MagnifierEffect::toggle() polling = true; effects->startMousePolling(); } + if (!m_texture) { + m_texture = new GLTexture(magnifier_size); + m_texture->setYInverted(false); + m_fbo = new GLRenderTarget(m_texture); + } } else { target_zoom = 1; if (polling) { polling = false; effects->stopMousePolling(); } + delete m_fbo; + delete m_texture; + m_fbo = NULL; + m_texture = NULL; } effects->addRepaint(magnifierArea().adjusted(-FRAME_WIDTH, -FRAME_WIDTH, FRAME_WIDTH, FRAME_WIDTH)); } diff --git a/effects/magnifier/magnifier.h b/effects/magnifier/magnifier.h index 0ea3adabae..0e4e6750d2 100644 --- a/effects/magnifier/magnifier.h +++ b/effects/magnifier/magnifier.h @@ -3,6 +3,7 @@ This file is part of the KDE project. Copyright (C) 2007 Lubos Lunak +Copyright (C) 2011 Martin Gräßlin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,12 +27,16 @@ along with this program. If not, see . namespace KWin { +class GLRenderTarget; +class GLTexture; + class MagnifierEffect : public Effect { Q_OBJECT public: MagnifierEffect(); + virtual ~MagnifierEffect(); virtual void reconfigure(ReconfigureFlags); virtual void prePaintScreen(ScreenPrePaintData& data, int time); virtual void paintScreen(int mask, QRegion region, ScreenPaintData& data); @@ -50,6 +55,8 @@ private: double target_zoom; bool polling; // Mouse polling QSize magnifier_size; + GLTexture *m_texture; + GLRenderTarget *m_fbo; }; } // namespace