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