2013-04-03 12:12:55 +00:00
From 9c17370c706e91c22b63e9c0a917c2463c23a091 Mon Sep 17 00:00:00 2001
From: Rabeeh Khoury <rabeeh@solid-run.com>
Date: Tue, 15 Jan 2013 16:27:29 +0200
Subject: [PATCH] Use Dove hardware graphics scaler
The theory behind this patch is to render to a smaller area and then use the hardware upscaler to upscale the graphics plane to the destination resolution.
For instance, going into system setting->system->Video output and choosing Graphics scaling to 1.5, will make 1080p resolution to rendering 1/1.5 of it's size (720p).
Rendering becomes much more faster, memory bandwidth on the LCD controller becomes half too.
Using this patch it's now possible to get higher fps on XBMC GUI
Signed-off-by: Rabeeh Khoury <rabeeh@solid-run.com>
---
xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp | 13 ++++--
xbmc/guilib/GraphicContext.cpp | 14 +++++++
xbmc/guilib/Resolution.h | 7 ++++
xbmc/settings/GUISettings.cpp | 7 ++++
xbmc/settings/GUIWindowSettingsCategory.cpp | 5 +++
xbmc/video/windows/GUIWindowFullScreen.cpp | 17 ++++++++
xbmc/windowing/X11/XRandR.cpp | 45 +++++++++++++++++++++
xbmc/windowing/X11/XRandR.h | 3 ++
8 files changed, 107 insertions(+), 4 deletions(-)
diff --git a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
index be37ab5..72343ca 100644
--- a/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
+++ b/xbmc/cores/VideoRenderers/DoveOverlayRenderer.cpp
@@ -205,11 +205,16 @@ bool CDoveOverlayRenderer::Configure(
return false;
}
- int interpolation = 3; // bi-linear interpolation
- if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_INTERPOLATION_MODE, &interpolation) != 0)
+ GRAPHICS_SCALING scale = (GRAPHICS_SCALING) g_guiSettings.GetInt("videoscreen.graphics_scaling");
+ if (scale == -1) scale=GR_SCALE_100;
+ if (scale == GR_SCALE_100) /* Scaler is set differently when using graphics scaler */
{
- CLog::Log(LOGERROR, "%s::%s - Failed to setup video interpolation mode", CLASSNAME, __func__);
- return false;
+ int interpolation = 3; // bi-linear interpolation
+ if (ioctl(m_overlayfd, DOVEFB_IOCTL_SET_INTERPOLATION_MODE, &interpolation) != 0)
+ {
+ CLog::Log(LOGERROR, "%s::%s - Failed to setup video interpolation mode", CLASSNAME, __func__);
+ return false;
+ }
}
struct _sColorKeyNAlpha alpha;
diff --git a/xbmc/guilib/GraphicContext.cpp b/xbmc/guilib/GraphicContext.cpp
index 94f248b..e5edfcd 100644
--- a/xbmc/guilib/GraphicContext.cpp
+++ b/xbmc/guilib/GraphicContext.cpp
@@ -626,6 +626,19 @@ void CGraphicContext::SetScalingResolution(const RESOLUTION_INFO &res, bool need
float fToWidth;
float fToHeight;
+#ifdef HAS_MARVELL_DOVE
+ GRAPHICS_SCALING scale = (GRAPHICS_SCALING) g_guiSettings.GetInt("videoscreen.graphics_scaling");
+ if (scale == -1) /* not configured */
+ scale = GR_SCALE_100;
+ {
+ fFromWidth = (float)res.iWidth;
+ fFromHeight = (float)res.iHeight;
+ fToPosX = (float)g_settings.m_ResInfo[m_Resolution].Overscan.left*100/scale;
+ fToPosY = (float)g_settings.m_ResInfo[m_Resolution].Overscan.top*100/scale;
+ fToWidth = (float)g_settings.m_ResInfo[m_Resolution].Overscan.right*100/scale - fToPosX;
+ fToHeight = (float)g_settings.m_ResInfo[m_Resolution].Overscan.bottom*100/scale - fToPosY;
+ }
+#else
{
fFromWidth = (float)res.iWidth;
fFromHeight = (float)res.iHeight;
@@ -634,6 +647,7 @@ void CGraphicContext::SetScalingResolution(const RESOLUTION_INFO &res, bool need
fToWidth = (float)g_settings.m_ResInfo[m_Resolution].Overscan.right - fToPosX;
fToHeight = (float)g_settings.m_ResInfo[m_Resolution].Overscan.bottom - fToPosY;
}
+#endif
if(!g_guiSkinzoom) // lookup gui setting if we didn't have it already
g_guiSkinzoom = (CSettingInt*)g_guiSettings.GetSetting("lookandfeel.skinzoom");
diff --git a/xbmc/guilib/Resolution.h b/xbmc/guilib/Resolution.h
index 66c4e85..a9b7d6c 100644
--- a/xbmc/guilib/Resolution.h
+++ b/xbmc/guilib/Resolution.h
@@ -63,6 +63,15 @@
VSYNC_DRIVER = 3
};
+#ifdef TARGET_MARVELL_DOVE
+enum GRAPHICS_SCALING {
+ GR_SCALE_100 = 100,
+ GR_SCALE_150 = 150,
+ GR_SCALE_200 = 200,
+ GR_SCALE_250 = 250
+};
+#endif
+
struct OVERSCAN
{
int left;
diff --git a/xbmc/settings/GUISettings.cpp b/xbmc/settings/GUISettings.cpp
index bb39c86..6f0ba5e 100644
--- a/xbmc/settings/GUISettings.cpp
+++ b/xbmc/settings/GUISettings.cpp
@@ -435,6 +435,15 @@
AddSeparator(vs, "videoscreen.sep1");
#endif
+#ifdef TARGET_MARVELL_DOVE
+ map<int,int> graphics_scaling;
+ graphics_scaling.insert(make_pair(37011,GR_SCALE_100));
+ graphics_scaling.insert(make_pair(37012,GR_SCALE_150));
+ graphics_scaling.insert(make_pair(37013,GR_SCALE_200));
+ graphics_scaling.insert(make_pair(37014,GR_SCALE_250));
+ AddInt(vs, "videoscreen.graphics_scaling", 37010, GR_SCALE_100, graphics_scaling, SPIN_CONTROL_TEXT);
+#endif
+
map<int,int> vsync;
#if defined(_LINUX) && !defined(TARGET_DARWIN)
vsync.insert(make_pair(13101,VSYNC_DRIVER));
diff --git a/xbmc/settings/GUIWindowSettingsCategory.cpp b/xbmc/settings/GUIWindowSettingsCategory.cpp
index d98107f..0ae1822 100644
--- a/xbmc/settings/GUIWindowSettingsCategory.cpp
+++ b/xbmc/settings/GUIWindowSettingsCategory.cpp
@@ -1490,6 +1490,11 @@ void CGUIWindowSettingsCategory::OnSettingChanged(BaseSettingControlPtr pSetting
CLog::Log(LOGERROR, "Unable to open vmeta clock settings file on sysfs");
fclose(Fh);
}
+ else if (strSetting.Equals("videoscreen.graphics_scaling"))
+ {
+ /* Fake as resolution changed - this to refresh aspect ratios of fonts vs. graphics */
+ g_graphicsContext.SetVideoResolution(g_graphicsContext.GetVideoResolution(), true);
+ }
#endif
else if (strSetting.Equals("videoscreen.vsync"))
{
diff --git a/xbmc/video/windows/GUIWindowFullScreen.cpp b/xbmc/video/windows/GUIWindowFullScreen.cpp
index 7b80926..24e2d98 100644
--- a/xbmc/video/windows/GUIWindowFullScreen.cpp
+++ b/xbmc/video/windows/GUIWindowFullScreen.cpp
@@ -1082,6 +1082,11 @@ void CGUIWindowFullScreen::RenderTTFSubtitles()
CStdString subtitleText = "How now brown cow";
if (g_application.m_pPlayer->GetCurrentSubtitle(subtitleText))
{
+#ifdef HAS_MARVELL_DOVE
+ GRAPHICS_SCALING scale = (GRAPHICS_SCALING) g_guiSettings.GetInt("videoscreen.graphics_scaling");
+ if (scale == -1) /* not configured */
+ scale = GR_SCALE_100;
+#endif
// Remove HTML-like tags from the subtitles until
subtitleText.Replace("\\r", "");
subtitleText.Replace("\r", "");
@@ -1105,7 +1110,11 @@ void CGUIWindowFullScreen::RenderTTFSubtitles()
RESOLUTION res = g_graphicsContext.GetVideoResolution();
g_graphicsContext.SetRenderingResolution(g_graphicsContext.GetResInfo(), false);
+#ifdef HAS_MARVELL_DOVE
+ float maxWidth = (float) g_settings.m_ResInfo[res].Overscan.right*100/scale - g_settings.m_ResInfo[res].Overscan.left;
+#else
float maxWidth = (float) g_settings.m_ResInfo[res].Overscan.right - g_settings.m_ResInfo[res].Overscan.left;
+#endif
m_subsLayout->Update(subtitleText, maxWidth * 0.9f, false, true); // true to force LTR reading order (most Hebrew subs are this format)
int subalign = g_guiSettings.GetInt("subtitles.align");
@@ -1115,7 +1124,11 @@ void CGUIWindowFullScreen::RenderTTFSubtitles()
float y = (float) g_settings.m_ResInfo[res].iSubtitles;
if (subalign == SUBTITLE_ALIGN_MANUAL)
+#ifdef HAS_MARVELL_DOVE
+ y = (float) g_settings.m_ResInfo[res].iSubtitles*100/scale - textHeight;
+#else
y = (float) g_settings.m_ResInfo[res].iSubtitles - textHeight;
+#endif
else
{
CRect SrcRect, DestRect;
@@ -1133,7 +1146,11 @@ void CGUIWindowFullScreen::RenderTTFSubtitles()
y += g_graphicsContext.GetHeight() - g_settings.m_ResInfo[res].iSubtitles;
y = std::max(y, (float) g_settings.m_ResInfo[res].Overscan.top);
+#ifdef HAS_MARVELL_DOVE
+ y = std::min(y, g_settings.m_ResInfo[res].Overscan.bottom*100/scale - textHeight);
+#else
y = std::min(y, g_settings.m_ResInfo[res].Overscan.bottom - textHeight);
+#endif
}
m_subsLayout->RenderOutline(x, y, 0, 0xFF000000, XBFONT_CENTER_X, maxWidth);
diff --git a/xbmc/windowing/X11/XRandR.cpp b/xbmc/windowing/X11/XRandR.cpp
index d8e9161..d23b76e 100644
--- a/xbmc/windowing/X11/XRandR.cpp
+++ b/xbmc/windowing/X11/XRandR.cpp
@@ -26,6 +26,11 @@
#include <sys/wait.h>
#include "system.h"
#include "PlatformInclude.h"
+#ifdef TARGET_MARVELL_DOVE
+#include <sys/mman.h>
+#include "guilib/Resolution.h"
+#include "settings/GUISettings.h"
+#endif
#include "utils/XBMCTinyXML.h"
#include "../xbmc/utils/log.h"
@@ -158,8 +163,44 @@ void CXRandR::RestoreState()
}
}
+#ifdef TARGET_MARVELL_DOVE
+#define MAP_SIZE 4096UL
+#define MAP_MASK (MAP_SIZE - 1)
+void CXRandR::ChangeGraphicsScaler(void)
+{
+ /* OK. Now this is a seriously ugly hack. Code needs to be re-written to support ioctl to driver !!! */
+ /* Code below originally from devmem2.c */
+ int fd;
+ off_t target_page = 0xf1820000; /* LCD Controller base address */
+ void *map_base;
+ unsigned int zoomed;
+ unsigned int gr_size;
+ int zx,zy;
+ GRAPHICS_SCALING scale = (GRAPHICS_SCALING) g_guiSettings.GetInt("videoscreen.graphics_scaling");
+ if (scale == -1) scale=GR_SCALE_100;
+ if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) {
+ CLog::Log(LOGERROR, "XRANDR: Unable to open /dev/mem");
+ return;
+ }
+ fflush(stdout);
+ map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, target_page);
+ zoomed = * (unsigned int *) (map_base + 0x108);
+ zx = zoomed & 0xffff;
+ zy = (zoomed & 0xffff0000) >> 16;
+ CLog::Log(LOGINFO, "XRANDR: Zoomed area is %dx%d, new area should be %dx%d\n",zx,zy,zx*100/scale,zy*100/scale);
+ gr_size = (zy*100/scale) & 0xffff;
+ gr_size = (gr_size << 16) | ((zx*100/scale) & 0xffff);
+ * (unsigned int *) (map_base + 0x104) = gr_size;
+ close(fd);
+}
+#endif
+
bool CXRandR::SetMode(XOutput output, XMode mode)
{
+#ifdef TARGET_MARVELL_DOVE
+ /* Required both on entrance and exit from SetMode. First entrance is required to get the scaler modified */
+ ChangeGraphicsScaler ();
+#endif
if ((output.name == m_currentOutput && mode.id == m_currentMode) || (output.name == "" && mode.id == ""))
return true;
@@ -256,6 +298,9 @@ bool CXRandR::SetMode(XOutput output, XMode mode)
if (WEXITSTATUS(status) != 0)
return false;
+#ifdef TARGET_MARVELL_DOVE
+ ChangeGraphicsScaler ();
+#endif
return true;
}
diff --git a/xbmc/windowing/X11/XRandR.h b/xbmc/windowing/X11/XRandR.h
index 2a269d0..95e4a1f 100644
--- a/xbmc/windowing/X11/XRandR.h
+++ b/xbmc/windowing/X11/XRandR.h
@@ -100,6 +100,9 @@ public:
void LoadCustomModeLinesToAllOutputs(void);
void SaveState();
void RestoreState();
+#ifdef TARGET_MARVELL_DOVE
+ void ChangeGraphicsScaler(void);
+#endif
//bool Has1080i();
//bool Has1080p();
//bool Has720p();
diff --git a/language/English/strings.po b/language/English/strings.po
index fcb9255..8f36605 100644
--- a/language/English/strings.po
+++ b/language/English/strings.po
@@ -11420,3 +11420,23 @@
msgctxt "#36041"
msgid "* Item folder"
msgstr ""
+
+msgctxt "#37010"
+msgid "Graphics Scaling"
+msgstr ""
+
+msgctxt "#37011"
+msgid "x1"
+msgstr ""
+
+msgctxt "#37012"
+msgid "x1.5"
+msgstr ""
+
+msgctxt "#37013"
+msgid "x2"
+msgstr ""
+
+msgctxt "#37014"
+msgid "x2.5"
+msgstr ""
2013-04-22 16:01:46 +00:00
--- a/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVMETA.cpp 2013-04-22 17:05:37.933955658 +0200
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Video/DVDVideoCodecVMETA.cpp 2013-04-22 17:06:19.447874572 +0200
@@ -43,6 +43,7 @@
#define CLASSNAME "CDVDVideoCodecVMETA"
#include "utils/BitstreamConverter.h"
+#include "settings/GUISettings.h"
#define ENABLE_MPEG1 // use vMeta for MPEG1 decoding