/xbmc/cores/VideoRenderers/LinuxRendererGL.h

http://github.com/xbmc/xbmc · C Header · 362 lines · 262 code · 68 blank · 32 comment · 3 complexity · 32021ad2de720d285965f2fcea1cef94 MD5 · raw file

  1. #ifndef LINUXRENDERERGL_RENDERER
  2. #define LINUXRENDERERGL_RENDERER
  3. /*
  4. * Copyright (C) 2007-2013 Team XBMC
  5. * http://xbmc.org
  6. *
  7. * This Program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2, or (at your option)
  10. * any later version.
  11. *
  12. * This Program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with XBMC; see the file COPYING. If not, see
  19. * <http://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #include "system.h"
  23. #ifdef HAS_GL
  24. #include "system_gl.h"
  25. #include "guilib/FrameBufferObject.h"
  26. #include "guilib/Shader.h"
  27. #include "settings/VideoSettings.h"
  28. #include "RenderFlags.h"
  29. #include "RenderFormats.h"
  30. #include "guilib/GraphicContext.h"
  31. #include "BaseRenderer.h"
  32. #include "threads/Event.h"
  33. class CRenderCapture;
  34. class CBaseTexture;
  35. namespace Shaders { class BaseYUV2RGBShader; }
  36. namespace Shaders { class BaseVideoFilterShader; }
  37. namespace VAAPI { struct CHolder; }
  38. namespace VDPAU { class CVdpauRenderPicture; }
  39. #undef ALIGN
  40. #define ALIGN(value, alignment) (((value)+((alignment)-1))&~((alignment)-1))
  41. #define CLAMP(a, min, max) ((a) > (max) ? (max) : ( (a) < (min) ? (min) : a ))
  42. #define AUTOSOURCE -1
  43. #define IMAGE_FLAG_WRITING 0x01 /* image is in use after a call to GetImage, caller may be reading or writing */
  44. #define IMAGE_FLAG_READING 0x02 /* image is in use after a call to GetImage, caller is only reading */
  45. #define IMAGE_FLAG_DYNAMIC 0x04 /* image was allocated due to a call to GetImage */
  46. #define IMAGE_FLAG_RESERVED 0x08 /* image is reserved, must be asked for specifically used to preserve images */
  47. #define IMAGE_FLAG_READY 0x16 /* image is ready to be uploaded to texture memory */
  48. #define IMAGE_FLAG_INUSE (IMAGE_FLAG_WRITING | IMAGE_FLAG_READING | IMAGE_FLAG_RESERVED)
  49. struct DRAWRECT
  50. {
  51. float left;
  52. float top;
  53. float right;
  54. float bottom;
  55. };
  56. struct YUVRANGE
  57. {
  58. int y_min, y_max;
  59. int u_min, u_max;
  60. int v_min, v_max;
  61. };
  62. struct YUVCOEF
  63. {
  64. float r_up, r_vp;
  65. float g_up, g_vp;
  66. float b_up, b_vp;
  67. };
  68. enum RenderMethod
  69. {
  70. RENDER_GLSL=0x01,
  71. RENDER_ARB=0x02,
  72. RENDER_SW=0x04,
  73. RENDER_VDPAU=0x08,
  74. RENDER_POT=0x10,
  75. RENDER_VAAPI=0x20,
  76. RENDER_CVREF = 0x40,
  77. };
  78. enum RenderQuality
  79. {
  80. RQ_LOW=1,
  81. RQ_SINGLEPASS,
  82. RQ_MULTIPASS,
  83. };
  84. #define PLANE_Y 0
  85. #define PLANE_U 1
  86. #define PLANE_V 2
  87. #define FIELD_FULL 0
  88. #define FIELD_TOP 1
  89. #define FIELD_BOT 2
  90. extern YUVRANGE yuv_range_lim;
  91. extern YUVRANGE yuv_range_full;
  92. extern YUVCOEF yuv_coef_bt601;
  93. extern YUVCOEF yuv_coef_bt709;
  94. extern YUVCOEF yuv_coef_ebu;
  95. extern YUVCOEF yuv_coef_smtp240m;
  96. class DllSwScale;
  97. class CLinuxRendererGL : public CBaseRenderer
  98. {
  99. public:
  100. CLinuxRendererGL();
  101. virtual ~CLinuxRendererGL();
  102. virtual void Update();
  103. virtual void SetupScreenshot() {};
  104. bool RenderCapture(CRenderCapture* capture);
  105. // Player functions
  106. virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags, ERenderFormat format, unsigned extended_formatl, unsigned int orientation);
  107. virtual bool IsConfigured() { return m_bConfigured; }
  108. virtual int GetImage(YV12Image *image, int source = AUTOSOURCE, bool readonly = false);
  109. virtual void ReleaseImage(int source, bool preserve = false);
  110. virtual void FlipPage(int source);
  111. virtual unsigned int PreInit();
  112. virtual void UnInit();
  113. virtual void Reset(); /* resets renderer after seek for example */
  114. virtual void Flush();
  115. virtual void ReleaseBuffer(int idx);
  116. virtual void SetBufferSize(int numBuffers) { m_NumYV12Buffers = numBuffers; }
  117. virtual unsigned int GetMaxBufferSize() { return NUM_BUFFERS; }
  118. virtual unsigned int GetProcessorSize();
  119. #ifdef HAVE_LIBVDPAU
  120. virtual void AddProcessor(VDPAU::CVdpauRenderPicture* vdpau, int index);
  121. #endif
  122. #ifdef HAVE_LIBVA
  123. virtual void AddProcessor(VAAPI::CHolder& holder, int index);
  124. #endif
  125. #ifdef TARGET_DARWIN
  126. virtual void AddProcessor(struct __CVBuffer *cvBufferRef, int index);
  127. #endif
  128. virtual void RenderUpdate(bool clear, DWORD flags = 0, DWORD alpha = 255);
  129. // Feature support
  130. virtual bool SupportsMultiPassRendering();
  131. virtual bool Supports(ERENDERFEATURE feature);
  132. virtual bool Supports(EDEINTERLACEMODE mode);
  133. virtual bool Supports(EINTERLACEMETHOD method);
  134. virtual bool Supports(ESCALINGMETHOD method);
  135. virtual EINTERLACEMETHOD AutoInterlaceMethod();
  136. virtual std::vector<ERenderFormat> SupportedFormats() { return m_formats; }
  137. protected:
  138. virtual void Render(DWORD flags, int renderBuffer);
  139. void ClearBackBuffer();
  140. void DrawBlackBars();
  141. bool ValidateRenderer();
  142. int NextYV12Texture();
  143. virtual bool ValidateRenderTarget();
  144. virtual void LoadShaders(int field=FIELD_FULL);
  145. void SetTextureFilter(GLenum method);
  146. void UpdateVideoFilter();
  147. // textures
  148. bool (CLinuxRendererGL::*m_textureUpload)(int index);
  149. void (CLinuxRendererGL::*m_textureDelete)(int index);
  150. bool (CLinuxRendererGL::*m_textureCreate)(int index);
  151. bool UploadYV12Texture(int index);
  152. void DeleteYV12Texture(int index);
  153. bool CreateYV12Texture(int index);
  154. bool UploadNV12Texture(int index);
  155. void DeleteNV12Texture(int index);
  156. bool CreateNV12Texture(int index);
  157. bool UploadVDPAUTexture(int index);
  158. void DeleteVDPAUTexture(int index);
  159. bool CreateVDPAUTexture(int index);
  160. bool UploadVDPAUTexture420(int index);
  161. void DeleteVDPAUTexture420(int index);
  162. bool CreateVDPAUTexture420(int index);
  163. bool UploadVAAPITexture(int index);
  164. void DeleteVAAPITexture(int index);
  165. bool CreateVAAPITexture(int index);
  166. bool UploadCVRefTexture(int index);
  167. void DeleteCVRefTexture(int index);
  168. bool CreateCVRefTexture(int index);
  169. bool UploadYUV422PackedTexture(int index);
  170. void DeleteYUV422PackedTexture(int index);
  171. bool CreateYUV422PackedTexture(int index);
  172. bool UploadRGBTexture(int index);
  173. void ToRGBFrame(YV12Image* im, unsigned flipIndexPlane, unsigned flipIndexBuf);
  174. void ToRGBFields(YV12Image* im, unsigned flipIndexPlaneTop, unsigned flipIndexPlaneBot, unsigned flipIndexBuf);
  175. void SetupRGBBuffer();
  176. void CalculateTextureSourceRects(int source, int num_planes);
  177. // renderers
  178. void RenderToFBO(int renderBuffer, int field, bool weave = false);
  179. void RenderFromFBO();
  180. void RenderSinglePass(int renderBuffer, int field); // single pass glsl renderer
  181. void RenderSoftware(int renderBuffer, int field); // single pass s/w yuv2rgb renderer
  182. void RenderVDPAU(int renderBuffer, int field); // render using vdpau hardware
  183. void RenderProgressiveWeave(int renderBuffer, int field); // render using vdpau hardware
  184. void RenderVAAPI(int renderBuffer, int field); // render using vdpau hardware
  185. struct
  186. {
  187. CFrameBufferObject fbo;
  188. float width, height;
  189. } m_fbo;
  190. int m_iYV12RenderBuffer;
  191. int m_NumYV12Buffers;
  192. int m_iLastRenderBuffer;
  193. bool m_bConfigured;
  194. bool m_bValidated;
  195. std::vector<ERenderFormat> m_formats;
  196. bool m_bImageReady;
  197. ERenderFormat m_format;
  198. GLenum m_textureTarget;
  199. unsigned short m_renderMethod;
  200. RenderQuality m_renderQuality;
  201. unsigned int m_flipindex; // just a counter to keep track of if a image has been uploaded
  202. // Raw data used by renderer
  203. int m_currentField;
  204. int m_reloadShaders;
  205. struct YUVPLANE
  206. {
  207. GLuint id;
  208. GLuint pbo;
  209. CRect rect;
  210. float width;
  211. float height;
  212. unsigned texwidth;
  213. unsigned texheight;
  214. //pixels per texel
  215. unsigned pixpertex_x;
  216. unsigned pixpertex_y;
  217. unsigned flipindex;
  218. };
  219. typedef YUVPLANE YUVPLANES[MAX_PLANES];
  220. typedef YUVPLANES YUVFIELDS[MAX_FIELDS];
  221. struct YUVBUFFER
  222. {
  223. YUVBUFFER();
  224. ~YUVBUFFER();
  225. YUVFIELDS fields;
  226. YV12Image image;
  227. unsigned flipindex; /* used to decide if this has been uploaded */
  228. GLuint pbo[MAX_PLANES];
  229. #ifdef HAVE_LIBVDPAU
  230. VDPAU::CVdpauRenderPicture *vdpau;
  231. #endif
  232. #ifdef HAVE_LIBVA
  233. VAAPI::CHolder& vaapi;
  234. #endif
  235. #ifdef TARGET_DARWIN_OSX
  236. struct __CVBuffer *cvBufferRef;
  237. #endif
  238. };
  239. typedef YUVBUFFER YUVBUFFERS[NUM_BUFFERS];
  240. // YV12 decoder textures
  241. // field index 0 is full image, 1 is odd scanlines, 2 is even scanlines
  242. YUVBUFFERS m_buffers;
  243. void LoadPlane( YUVPLANE& plane, int type, unsigned flipindex
  244. , unsigned width, unsigned height
  245. , int stride, int bpp, void* data, GLuint* pbo = NULL );
  246. void GetPlaneTextureSize(YUVPLANE& plane);
  247. Shaders::BaseYUV2RGBShader *m_pYUVShader;
  248. Shaders::BaseVideoFilterShader *m_pVideoFilterShader;
  249. ESCALINGMETHOD m_scalingMethod;
  250. ESCALINGMETHOD m_scalingMethodGui;
  251. // clear colour for "black" bars
  252. float m_clearColour;
  253. // software scale library (fallback if required gl version is not available)
  254. DllSwScale *m_dllSwScale;
  255. BYTE *m_rgbBuffer; // if software scale is used, this will hold the result image
  256. unsigned int m_rgbBufferSize;
  257. GLuint m_rgbPbo;
  258. struct SwsContext *m_context;
  259. void BindPbo(YUVBUFFER& buff);
  260. void UnBindPbo(YUVBUFFER& buff);
  261. bool m_pboSupported;
  262. bool m_pboUsed;
  263. bool m_nonLinStretch;
  264. bool m_nonLinStretchGui;
  265. float m_pixelRatio;
  266. };
  267. inline int NP2( unsigned x ) {
  268. #if defined(TARGET_POSIX) && !defined(__POWERPC__) && !defined(__PPC__) && !defined(__arm__)
  269. // If there are any issues compiling this, just append a ' && 0'
  270. // to the above to make it '#if defined(TARGET_POSIX) && 0'
  271. // Linux assembly is AT&T Unix style, not Intel style
  272. unsigned y;
  273. __asm__("dec %%ecx \n"
  274. "movl $1, %%eax \n"
  275. "bsr %%ecx,%%ecx \n"
  276. "inc %%ecx \n"
  277. "shl %%cl, %%eax \n"
  278. "movl %%eax, %0 \n"
  279. :"=r"(y)
  280. :"c"(x)
  281. :"%eax");
  282. return y;
  283. #else
  284. --x;
  285. x |= x >> 1;
  286. x |= x >> 2;
  287. x |= x >> 4;
  288. x |= x >> 8;
  289. x |= x >> 16;
  290. return ++x;
  291. #endif
  292. }
  293. #endif
  294. #endif