[guilib] fix labelcontrols with auto width always being marked as dirty if they speci...
[vuplus_xbmc] / xbmc / guilib / GraphicContext.h
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, see
17  *  <http://www.gnu.org/licenses/>.
18  *
19  */
20
21 /*!
22 \file GraphicContext.h
23 \brief
24 */
25
26 #ifndef GUILIB_GRAPHICCONTEXT_H
27 #define GUILIB_GRAPHICCONTEXT_H
28
29 #pragma once
30
31 #ifdef __GNUC__
32 // under gcc, inline will only take place if optimizations are applied (-O). this will force inline even whith optimizations.
33 #define XBMC_FORCE_INLINE __attribute__((always_inline))
34 #else
35 #define XBMC_FORCE_INLINE
36 #endif
37
38
39 #include <vector>
40 #include <stack>
41 #include <map>
42 #include "threads/CriticalSection.h"  // base class
43 #include "TransformMatrix.h"        // for the members m_guiTransform etc.
44 #include "Geometry.h"               // for CRect/CPoint
45 #include "gui3d.h"
46 #include "utils/StdString.h"
47 #include "Resolution.h"
48 #include "utils/GlobalsHandling.h"
49 #include "DirtyRegion.h"
50 #include "settings/lib/ISettingCallback.h"
51 #include "rendering/RenderSystem.h"
52
53 enum VIEW_TYPE { VIEW_TYPE_NONE = 0,
54                  VIEW_TYPE_LIST,
55                  VIEW_TYPE_ICON,
56                  VIEW_TYPE_BIG_LIST,
57                  VIEW_TYPE_BIG_ICON,
58                  VIEW_TYPE_WIDE,
59                  VIEW_TYPE_BIG_WIDE,
60                  VIEW_TYPE_WRAP,
61                  VIEW_TYPE_BIG_WRAP,
62                  VIEW_TYPE_INFO,
63                  VIEW_TYPE_BIG_INFO,
64                  VIEW_TYPE_AUTO,
65                  VIEW_TYPE_MAX };
66
67 enum AdjustRefreshRate
68 {
69   ADJUST_REFRESHRATE_OFF          = 0,
70   ADJUST_REFRESHRATE_ALWAYS,
71   ADJUST_REFRESHRATE_ON_STARTSTOP
72 };
73
74 class CGraphicContext : public CCriticalSection,
75                         public ISettingCallback
76 {
77 public:
78   CGraphicContext(void);
79   virtual ~CGraphicContext(void);
80
81   virtual void OnSettingChanged(const CSetting *setting);
82
83   // the following two functions should wrap any
84   // GL calls to maintain thread safety
85   void BeginPaint(bool lock=true);
86   void EndPaint(bool lock=true);
87
88   int GetWidth() const { return m_iScreenWidth; }
89   int GetHeight() const { return m_iScreenHeight; }
90   float GetFPS() const;
91   const CStdString& GetMediaDir() const { return m_strMediaDir; }
92   void SetMediaDir(const CStdString& strMediaDir);
93   bool SetViewPort(float fx, float fy , float fwidth, float fheight, bool intersectPrevious = false);
94   void RestoreViewPort();
95
96   void SetScissors(const CRect &rect);
97   void ResetScissors();
98   const CRect &GetScissors() const { return m_scissors; }
99
100   const CRect GetViewWindow() const;
101   void SetViewWindow(float left, float top, float right, float bottom);
102   bool IsFullScreenRoot() const;
103   bool ToggleFullScreenRoot();
104   void SetFullScreenVideo(bool bOnOff);
105   bool IsFullScreenVideo() const;
106   bool IsCalibrating() const;
107   void SetCalibrating(bool bOnOff);
108   bool IsValidResolution(RESOLUTION res);
109   void SetVideoResolution(RESOLUTION res, bool forceUpdate = false);
110   RESOLUTION GetVideoResolution() const;
111   void ResetOverscan(RESOLUTION res, OVERSCAN &overscan);
112   void ResetOverscan(RESOLUTION_INFO &resinfo);
113   void ResetScreenParameters(RESOLUTION res);
114   void Lock() { lock(); }
115   void Unlock() { unlock(); }
116   void CaptureStateBlock();
117   void ApplyStateBlock();
118   void Clear(color_t color = 0);
119   void GetAllowedResolutions(std::vector<RESOLUTION> &res);
120
121   // output scaling
122   const RESOLUTION_INFO GetResInfo() const
123   {
124     return GetResInfo(m_Resolution);
125   }
126   const RESOLUTION_INFO GetResInfo(RESOLUTION res) const;
127   void SetResInfo(RESOLUTION res, const RESOLUTION_INFO& info);
128
129   /* \brief Get UI scaling information from a given resolution to the screen resolution.
130    Takes account of overscan and UI zooming.
131    \param res the resolution to scale from.
132    \param scaleX [out] the scaling amount in the X direction.
133    \param scaleY [out] the scaling amount in the Y direction.
134    \param matrix [out] if non-NULL, a suitable transformation from res to screen resolution is set.
135    */
136   void GetGUIScaling(const RESOLUTION_INFO &res, float &scaleX, float &scaleY, TransformMatrix *matrix = NULL);
137
138   void SetRenderingResolution(const RESOLUTION_INFO &res, bool needsScaling);  ///< Sets scaling up for rendering
139   void SetScalingResolution(const RESOLUTION_INFO &res, bool needsScaling);    ///< Sets scaling up for skin loading etc.
140   float GetScalingPixelRatio() const;
141   void Flip(const CDirtyRegionList& dirty);
142   void InvertFinalCoords(float &x, float &y) const;
143   inline float ScaleFinalXCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.matrix.TransformXCoord(x, y, 0); }
144   inline float ScaleFinalYCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.matrix.TransformYCoord(x, y, 0); }
145   inline float ScaleFinalZCoord(float x, float y) const XBMC_FORCE_INLINE { return m_finalTransform.matrix.TransformZCoord(x, y, 0); }
146   inline void ScaleFinalCoords(float &x, float &y, float &z) const XBMC_FORCE_INLINE { m_finalTransform.matrix.TransformPosition(x, y, z); }
147   bool RectIsAngled(float x1, float y1, float x2, float y2) const;
148
149   inline float GetGUIScaleX() const XBMC_FORCE_INLINE { return m_finalTransform.scaleX; }
150   inline float GetGUIScaleY() const XBMC_FORCE_INLINE { return m_finalTransform.scaleY; }
151   inline color_t MergeAlpha(color_t color) const XBMC_FORCE_INLINE
152   {
153     color_t alpha = m_finalTransform.matrix.TransformAlpha((color >> 24) & 0xff);
154     if (alpha > 255) alpha = 255;
155     return ((alpha << 24) & 0xff000000) | (color & 0xffffff);
156   }
157
158   void SetOrigin(float x, float y);
159   void RestoreOrigin();
160   void SetCameraPosition(const CPoint &camera);
161   void SetStereoView(RENDER_STEREO_VIEW view);
162   RENDER_STEREO_VIEW GetStereoView()  { return m_stereoView; }
163   void SetStereoMode(RENDER_STEREO_MODE mode) { m_nextStereoMode = mode; }
164   RENDER_STEREO_MODE GetStereoMode()  { return m_stereoMode; }
165   void RestoreCameraPosition();
166   /*! \brief Set a region in which to clip all rendering
167    Anything that is rendered after setting a clip region will be clipped so that no part renders
168    outside of the clip region.  Successive calls to SetClipRegion intersect the clip region, which
169    means the clip region may eventually become an empty set.  In this case SetClipRegion returns false
170    to indicate that no rendering need be performed.
171
172    This call must be matched with a RestoreClipRegion call unless SetClipRegion returns false.
173
174    Usage should be of the form:
175
176      if (SetClipRegion(x, y, w, h))
177      {
178        ...
179        perform rendering
180        ...
181        RestoreClipRegion();
182      }
183
184    \param x the left-most coordinate of the clip region
185    \param y the top-most coordinate of the clip region
186    \param w the width of the clip region
187    \param h the height of the clip region
188    \returns true if the region is set and the result is non-empty. Returns false if the resulting region is empty.
189    \sa RestoreClipRegion
190    */
191   bool SetClipRegion(float x, float y, float w, float h);
192
193    /*! \brief Restore a clip region to the previous clip region (if any) prior to the last SetClipRegion call
194     This function should be within an if (SetClipRegion(x,y,w,h)) block.
195     \sa SetClipRegion
196     */
197   void RestoreClipRegion();
198   void ApplyHardwareTransform();
199   void RestoreHardwareTransform();
200   void ClipRect(CRect &vertex, CRect &texture, CRect *diffuse = NULL);
201   inline void AddGUITransform()
202   {
203     m_transforms.push(m_finalTransform);
204     m_finalTransform = m_guiTransform;
205   }
206   inline TransformMatrix AddTransform(const TransformMatrix &matrix)
207   {
208     m_transforms.push(m_finalTransform);
209     m_finalTransform.matrix *= matrix;
210     return m_finalTransform.matrix;
211   }
212   inline void SetTransform(const TransformMatrix &matrix)
213   {
214    m_transforms.push(m_finalTransform);
215    m_finalTransform.matrix = matrix;
216   }
217   inline void SetTransform(const TransformMatrix &matrix, float scaleX, float scaleY)
218   {
219     m_transforms.push(m_finalTransform);
220     m_finalTransform.matrix = matrix;
221     m_finalTransform.scaleX = scaleX;
222     m_finalTransform.scaleY = scaleY;
223   }
224   inline void RemoveTransform()
225   {
226     if (!m_transforms.empty())
227     {
228       m_finalTransform = m_transforms.top();
229       m_transforms.pop();
230     }
231   }
232
233   /* modifies final coordinates according to stereo mode if needed */
234   CRect StereoCorrection(const CRect &rect) const;
235   CPoint StereoCorrection(const CPoint &point) const;
236
237   CRect generateAABB(const CRect &rect) const;
238
239 protected:
240   std::stack<CRect> m_viewStack;
241
242   int m_iScreenHeight;
243   int m_iScreenWidth;
244   int m_iScreenId;
245   CStdString m_strMediaDir;
246   CRect m_videoRect;
247   bool m_bFullScreenRoot;
248   bool m_bFullScreenVideo;
249   bool m_bCalibrating;
250   RESOLUTION m_Resolution;
251
252 private:
253   class UITransform
254   {
255   public:
256     UITransform() : matrix(), scaleX(1.0f), scaleY(1.0f) {};
257     UITransform(const TransformMatrix &m, const float sX = 1.0f, const float sY = 1.0f) : matrix(m), scaleX(sX), scaleY(sY) { };
258     void Reset() { matrix.Reset(); scaleX = scaleY = 1.0f; };
259
260     TransformMatrix matrix;
261     float scaleX;
262     float scaleY;
263   };
264   void UpdateCameraPosition(const CPoint &camera);
265   RESOLUTION_INFO m_windowResolution;
266   std::stack<CPoint> m_cameras;
267   std::stack<CPoint> m_origins;
268   std::stack<CRect>  m_clipRegions;
269
270   UITransform m_guiTransform;
271   UITransform m_finalTransform;
272   std::stack<UITransform> m_transforms;
273   RENDER_STEREO_VIEW m_stereoView;
274   RENDER_STEREO_MODE m_stereoMode;
275   RENDER_STEREO_MODE m_nextStereoMode;
276
277   CRect m_scissors;
278 };
279
280 /*!
281  \ingroup graphics
282  \brief
283  */
284
285 XBMC_GLOBAL(CGraphicContext,g_graphicsContext);
286
287 #endif