mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 10:22:49 +00:00
kwin: implement option to set the X11 picture filter to any of the currently supported, default to "good"
obviously using the "good" filter as default can have a performance impact but if the system cannot handle it the option is there Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
ba3c114047
commit
f9f7c94639
9 changed files with 111 additions and 58 deletions
|
@ -155,7 +155,6 @@ void MagnifierEffect::paintScreen(int mask, QRegion region, ScreenPaintData& dat
|
|||
xcb_render_set_picture_filter(connection(), *m_picture, 4, const_cast<char*>("good"), 0, NULL);
|
||||
xcb_render_composite(connection(), XCB_RENDER_PICT_OP_SRC, *m_picture, 0, effects->xrenderBufferPicture(),
|
||||
0, 0, 0, 0, area.x(), area.y(), area.width(), area.height() );
|
||||
xcb_render_set_picture_filter(connection(), *m_picture, 4, const_cast<char*>("fast"), 0, NULL);
|
||||
xcb_render_set_picture_transform(connection(), *m_picture, identity);
|
||||
const xcb_rectangle_t rects[4] = {
|
||||
{ int16_t(area.x()+FRAME_WIDTH), int16_t(area.y()), uint16_t(area.width()-FRAME_WIDTH), uint16_t(FRAME_WIDTH)},
|
||||
|
|
|
@ -50,6 +50,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
#include <KPluginLoader>
|
||||
#include <KIcon>
|
||||
|
||||
static int s_xrenderfilter = 1; // KWin::Scene::ImageFilterGood
|
||||
|
||||
K_PLUGIN_FACTORY(KWinCompositingConfigFactory,
|
||||
registerPlugin<KWin::KWinCompositingConfig>();
|
||||
)
|
||||
|
@ -58,7 +60,6 @@ K_EXPORT_PLUGIN(KWinCompositingConfigFactory("kcmkwincompositing"))
|
|||
namespace KWin
|
||||
{
|
||||
|
||||
|
||||
ConfirmDialog::ConfirmDialog() :
|
||||
KTimerDialog(10000, KTimerDialog::CountDown, 0,
|
||||
i18n("Confirm Desktop Effects Change"), KTimerDialog::Ok | KTimerDialog::Cancel,
|
||||
|
@ -364,7 +365,7 @@ void KWinCompositingConfig::loadAdvancedTab()
|
|||
ui.windowThumbnails->setCurrentIndex(1);
|
||||
ui.unredirectFullscreen->setChecked(config.readEntry("UnredirectFullscreen", false));
|
||||
|
||||
ui.xrScaleFilter->setCurrentIndex((int)config.readEntry("XRenderSmoothScale", false));
|
||||
ui.xrScaleFilter->setCurrentIndex(config.readEntry("XRenderFilter", s_xrenderfilter));
|
||||
|
||||
alignGuiToCompositingType(ui.compositingType->currentIndex());
|
||||
}
|
||||
|
@ -464,7 +465,7 @@ bool KWinCompositingConfig::saveAdvancedTab()
|
|||
}
|
||||
|
||||
if (config.readEntry("HiddenPreviews", 5) != hps[ ui.windowThumbnails->currentIndex()]
|
||||
|| (int)config.readEntry("XRenderSmoothScale", false) != ui.xrScaleFilter->currentIndex()
|
||||
|| config.readEntry("XRenderFilter", s_xrenderfilter) != ui.xrScaleFilter->currentIndex()
|
||||
|| config.readEntry("Backend") != ui.compositingType->currentText()) {
|
||||
advancedChanged = true;
|
||||
}
|
||||
|
@ -474,7 +475,7 @@ bool KWinCompositingConfig::saveAdvancedTab()
|
|||
config.writeEntry("HiddenPreviews", hps[ ui.windowThumbnails->currentIndex()]);
|
||||
config.writeEntry("UnredirectFullscreen", ui.unredirectFullscreen->isChecked());
|
||||
|
||||
config.writeEntry("XRenderSmoothScale", ui.xrScaleFilter->currentIndex() == 1);
|
||||
config.writeEntry("XRenderFilter", ui.xrScaleFilter->currentIndex());
|
||||
|
||||
return advancedChanged;
|
||||
}
|
||||
|
@ -692,7 +693,7 @@ void KWinCompositingConfig::defaults()
|
|||
ui.compositingType->setCurrentIndex(XRENDER_INDEX);
|
||||
ui.windowThumbnails->setCurrentIndex(1);
|
||||
ui.unredirectFullscreen->setChecked(false);
|
||||
ui.xrScaleFilter->setCurrentIndex(0);
|
||||
ui.xrScaleFilter->setCurrentIndex(s_xrenderfilter);
|
||||
}
|
||||
|
||||
QString KWinCompositingConfig::quickHelp() const
|
||||
|
|
|
@ -547,28 +547,68 @@
|
|||
<item>
|
||||
<widget class="QComboBox" name="xrScaleFilter">
|
||||
<property name="toolTip">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'Segoe'; font-size:8pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Crisp:</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">XRenderSetPictureFilter(&quot;fast&quot;)</span> - Pretty fast on all GPUs but looks bricky</p>
|
||||
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Smooth:</span></p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-style:italic;">XRenderSetPictureFilter(&quot;good&quot;) </span>- linear blending.</p>
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Fast enough on newer nvidia GPUs and maybe others but also can be <span style=" text-decoration: underline;">very</span> slow, you will have to try it.</p></body></html></string>
|
||||
<string>
|
||||
<b>Fast:</b><br/>
|
||||
<i>XRenderSetPictureFilter("fast")</i> - pretty fast on all GPUs but looks bricky
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Good:</b><br/>
|
||||
<i>XRenderSetPictureFilter("good")</i> - linear blending, fast enough on newer GPUs and maybe others but also can be slow (default)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Best:</b><br/>
|
||||
<i>XRenderSetPictureFilter("best")</i> - best filter there is, can be <u>very</u> slow
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Nearest:</b><br/>
|
||||
<i>XRenderSetPictureFilter("nearest")</i>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Bilinear:</b><br/>
|
||||
<i>XRenderSetPictureFilter("bilinear")</i>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>Convolution:</b><br/>
|
||||
<i>XRenderSetPictureFilter("convolution")</i>
|
||||
</p>
|
||||
</string>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Crisp</string>
|
||||
<string>Fast</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Smooth (slower)</string>
|
||||
<string>Good</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Best</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Nearest</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Bilinear</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Convolution</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
|
|
|
@ -235,8 +235,8 @@
|
|||
<entry name="Enabled" type="Bool">
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="XRenderSmoothScale" type="Bool">
|
||||
<default>false</default>
|
||||
<entry name="XRenderFilter" type="UInt">
|
||||
<default>1</default>
|
||||
</entry>
|
||||
<entry name="HiddenPreviews" type="Int">
|
||||
<default>5</default>
|
||||
|
|
|
@ -99,7 +99,7 @@ Options::Options(QObject *parent)
|
|||
, m_compositingInitialized(Options::defaultCompositingInitialized())
|
||||
, m_hiddenPreviews(Options::defaultHiddenPreviews())
|
||||
, m_unredirectFullscreen(Options::defaultUnredirectFullscreen())
|
||||
, m_xrenderSmoothScale(Options::defaultXrenderSmoothScale())
|
||||
, m_xrenderFilter(Options::defaultXrenderFilter())
|
||||
, m_maxFpsInterval(Options::defaultMaxFpsInterval())
|
||||
, m_refreshRate(Options::defaultRefreshRate())
|
||||
, m_vBlankTime(Options::defaultVBlankTime())
|
||||
|
@ -602,13 +602,13 @@ void Options::setUnredirectFullscreen(bool unredirectFullscreen)
|
|||
emit unredirectFullscreenChanged();
|
||||
}
|
||||
|
||||
void Options::setXrenderSmoothScale(bool xrenderSmoothScale)
|
||||
void Options::setXrenderFilter(uint xrenderFilter)
|
||||
{
|
||||
if (m_xrenderSmoothScale == xrenderSmoothScale) {
|
||||
if (m_xrenderFilter == xrenderFilter) {
|
||||
return;
|
||||
}
|
||||
m_xrenderSmoothScale = xrenderSmoothScale;
|
||||
emit xrenderSmoothScaleChanged();
|
||||
m_xrenderFilter = xrenderFilter;
|
||||
emit xrenderFilterChanged();
|
||||
}
|
||||
|
||||
void Options::setMaxFpsInterval(qint64 maxFpsInterval)
|
||||
|
@ -792,7 +792,7 @@ void Options::reloadCompositingSettings(bool force)
|
|||
KSharedConfig::Ptr _config = KGlobal::config();
|
||||
KConfigGroup config(_config, "Compositing");
|
||||
|
||||
m_xrenderSmoothScale = config.readEntry("XRenderSmoothScale", false);
|
||||
m_xrenderFilter = config.readEntry("XRenderFilter", 1);
|
||||
|
||||
HiddenPreviews previews = Options::defaultHiddenPreviews();
|
||||
// 4 - off, 5 - shown, 6 - always, other are old values
|
||||
|
|
|
@ -162,7 +162,7 @@ class Options : public QObject, public KDecorationOptions
|
|||
* 2 = try trilinear when transformed; else 1,
|
||||
* -1 = auto
|
||||
**/
|
||||
Q_PROPERTY(bool xrenderSmoothScale READ isXrenderSmoothScale WRITE setXrenderSmoothScale NOTIFY xrenderSmoothScaleChanged)
|
||||
Q_PROPERTY(uint xrenderFilter READ xrenderFilter WRITE setXrenderFilter NOTIFY xrenderFilterChanged)
|
||||
Q_PROPERTY(qint64 maxFpsInterval READ maxFpsInterval WRITE setMaxFpsInterval NOTIFY maxFpsIntervalChanged)
|
||||
Q_PROPERTY(uint refreshRate READ refreshRate WRITE setRefreshRate NOTIFY refreshRateChanged)
|
||||
Q_PROPERTY(qint64 vBlankTime READ vBlankTime WRITE setVBlankTime NOTIFY vBlankTimeChanged)
|
||||
|
@ -484,8 +484,8 @@ public:
|
|||
return m_unredirectFullscreen;
|
||||
}
|
||||
// XRender
|
||||
bool isXrenderSmoothScale() const {
|
||||
return m_xrenderSmoothScale;
|
||||
uint xrenderFilter() const {
|
||||
return m_xrenderFilter;
|
||||
}
|
||||
|
||||
qint64 maxFpsInterval() const {
|
||||
|
@ -549,7 +549,7 @@ public:
|
|||
void setCompositingInitialized(bool compositingInitialized);
|
||||
void setHiddenPreviews(int hiddenPreviews);
|
||||
void setUnredirectFullscreen(bool unredirectFullscreen);
|
||||
void setXrenderSmoothScale(bool xrenderSmoothScale);
|
||||
void setXrenderFilter(uint xrenderFilter);
|
||||
void setMaxFpsInterval(qint64 maxFpsInterval);
|
||||
void setRefreshRate(uint refreshRate);
|
||||
void setVBlankTime(qint64 vBlankTime);
|
||||
|
@ -624,8 +624,8 @@ public:
|
|||
static bool defaultUnredirectFullscreen() {
|
||||
return false;
|
||||
}
|
||||
static bool defaultXrenderSmoothScale() {
|
||||
return false;
|
||||
static uint defaultXrenderFilter() {
|
||||
return 1;
|
||||
}
|
||||
static qint64 defaultMaxFpsInterval() {
|
||||
return (1 * 1000 * 1000 * 1000) /60.0; // nanoseconds / Hz
|
||||
|
@ -707,7 +707,7 @@ Q_SIGNALS:
|
|||
void compositingInitializedChanged();
|
||||
void hiddenPreviewsChanged();
|
||||
void unredirectFullscreenChanged();
|
||||
void xrenderSmoothScaleChanged();
|
||||
void xrenderFilterChanged();
|
||||
void maxFpsIntervalChanged();
|
||||
void refreshRateChanged();
|
||||
void vBlankTimeChanged();
|
||||
|
@ -745,7 +745,7 @@ private:
|
|||
bool m_compositingInitialized;
|
||||
HiddenPreviews m_hiddenPreviews;
|
||||
bool m_unredirectFullscreen;
|
||||
bool m_xrenderSmoothScale;
|
||||
uint m_xrenderFilter;
|
||||
qint64 m_maxFpsInterval;
|
||||
// Settings that should be auto-detected
|
||||
uint m_refreshRate;
|
||||
|
|
|
@ -444,7 +444,7 @@ void Scene::screenGeometryChanged(const QSize &size)
|
|||
|
||||
Scene::Window::Window(Toplevel * c)
|
||||
: toplevel(c)
|
||||
, filter(ImageFilterFast)
|
||||
, filter(ImageFilterGood)
|
||||
, m_shadow(NULL)
|
||||
, m_currentPixmap()
|
||||
, m_previousPixmap()
|
||||
|
|
|
@ -93,7 +93,14 @@ public:
|
|||
PAINT_SCREEN_BACKGROUND_FIRST = 1 << 6,
|
||||
};
|
||||
// types of filtering available
|
||||
enum ImageFilterType { ImageFilterFast, ImageFilterGood };
|
||||
enum ImageFilterType {
|
||||
ImageFilterFast,
|
||||
ImageFilterGood,
|
||||
ImageFilterBest,
|
||||
ImageFilterNearest,
|
||||
ImageFilterBilinear,
|
||||
ImageFilterConvolution
|
||||
};
|
||||
// there's nothing to paint (adjust time_diff later)
|
||||
virtual void idle();
|
||||
virtual OverlayWindow* overlayWindow() = 0;
|
||||
|
|
|
@ -413,16 +413,6 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat
|
|||
if (pic == XCB_RENDER_PICTURE_NONE) // The render format can be null for GL and/or Xv visuals
|
||||
return;
|
||||
toplevel->resetDamage();
|
||||
// set picture filter
|
||||
if (options->isXrenderSmoothScale()) { // only when forced, it's slow
|
||||
if (mask & PAINT_WINDOW_TRANSFORMED)
|
||||
filter = ImageFilterGood;
|
||||
else if (mask & PAINT_SCREEN_TRANSFORMED)
|
||||
filter = ImageFilterGood;
|
||||
else
|
||||
filter = ImageFilterFast;
|
||||
} else
|
||||
filter = ImageFilterFast;
|
||||
// do required transformations
|
||||
const QRect wr = mapToScreen(mask, data, QRect(0, 0, width(), height()));
|
||||
QRect cr = QRect(toplevel->clientPos(), toplevel->clientSize()); // Client rect (in the window)
|
||||
|
@ -510,9 +500,7 @@ void SceneXrender::Window::performPaint(int mask, QRegion region, WindowPaintDat
|
|||
}
|
||||
} else {
|
||||
xcb_render_set_picture_transform(connection(), pic, xform);
|
||||
if (filter == ImageFilterGood) {
|
||||
setPictureFilter(pic, KWin::Scene::ImageFilterGood);
|
||||
}
|
||||
setPictureFilter(pic, filter);
|
||||
|
||||
//BEGIN OF STUPID RADEON HACK
|
||||
// This is needed to avoid hitting a fallback in the radeon driver.
|
||||
|
@ -717,8 +705,6 @@ xcb_render_composite(connection(), XCB_RENDER_PICT_OP_OVER, _PART_, decorationAl
|
|||
}
|
||||
if (scaled && !blitInTempPixmap) {
|
||||
xcb_render_set_picture_transform(connection(), pic, identity);
|
||||
if (filter == ImageFilterGood)
|
||||
setPictureFilter(pic, KWin::Scene::ImageFilterFast);
|
||||
if (!window()->hasAlpha()) {
|
||||
const uint32_t values[] = {XCB_RENDER_REPEAT_NONE};
|
||||
xcb_render_change_picture(connection(), pic, XCB_RENDER_CP_REPEAT, values);
|
||||
|
@ -732,12 +718,32 @@ void SceneXrender::Window::setPictureFilter(xcb_render_picture_t pic, Scene::Ima
|
|||
{
|
||||
QByteArray filterName;
|
||||
switch (filter) {
|
||||
case KWin::Scene::ImageFilterFast:
|
||||
filterName = QByteArray("fast");
|
||||
break;
|
||||
case KWin::Scene::ImageFilterGood:
|
||||
filterName = QByteArray("good");
|
||||
break;
|
||||
case KWin::Scene::ImageFilterFast: {
|
||||
filterName = QByteArray("fast");
|
||||
break;
|
||||
}
|
||||
case KWin::Scene::ImageFilterGood: {
|
||||
filterName = QByteArray("good");
|
||||
break;
|
||||
}
|
||||
case KWin::Scene::ImageFilterBest: {
|
||||
filterName = QByteArray("best");
|
||||
break;
|
||||
}
|
||||
/* Filters included in 0.6 */
|
||||
case KWin::Scene::ImageFilterNearest: {
|
||||
filterName = QByteArray("nearest");
|
||||
break;
|
||||
}
|
||||
case KWin::Scene::ImageFilterBilinear: {
|
||||
filterName = QByteArray("bilinear");
|
||||
break;
|
||||
}
|
||||
/* Filters included in 0.10 */
|
||||
case KWin::Scene::ImageFilterConvolution: {
|
||||
filterName = QByteArray("convolution");
|
||||
break;
|
||||
}
|
||||
}
|
||||
xcb_render_set_picture_filter(connection(), pic, filterName.length(), filterName.constData(), 0, NULL);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue