/****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg Copyright (C) 2012-2016 Wang Bin * This file is part of QtAV (from 2014) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ******************************************************************************/ #ifndef QTAV_VIDEOSHADER_P_H #define QTAV_VIDEOSHADER_P_H #include "OpenGLTypes.h" #include "VideoFrame.h" #include "ColorTransform.h" #include #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) #include #include #include #else #if QT_VERSION >= QT_VERSION_CHECK(4, 8, 0) #include #endif #include #include typedef QGLBuffer QOpenGLBuffer; #define QOpenGLShaderProgram QGLShaderProgram #define QOpenGLShader QGLShader #define QOpenGLFunctions QGLFunctions #define QOpenGLContext QGLContext #endif namespace FAV { // can not move to OpenGLHelper.h because that's not public/private header enum ShaderType { VertexShader, FragmentShader, ShaderTypeCount }; class VideoShader; class Q_AV_PRIVATE_EXPORT VideoShaderPrivate : public DPtrPrivate { public: VideoShaderPrivate() : owns_program(false) , rebuild_program(false) , update_builtin_uniforms(true) , program(0) , u_Matrix(-1) , u_colorMatrix(-1) , u_to8(-1) , u_opacity(-1) , u_c(-1) , material_type(0) , texture_target(GL_TEXTURE_2D) {} virtual ~VideoShaderPrivate() { if (owns_program && program) { if (QOpenGLContext::currentContext()) { // FIXME: may be not called from renderering thread. so we still have to detach shaders program->removeAllShaders(); } delete program; } program = 0; } bool owns_program; // shader program is not created by this. e.g. scene graph create it's own program and we store it here bool rebuild_program; bool update_builtin_uniforms; //builtin uniforms are static, set the values once is enough if no change QOpenGLShaderProgram *program; int u_Matrix; int u_colorMatrix; int u_to8; int u_opacity; int u_c; int u_texelSize; int u_textureSize; #if (MODEL_360) // T&F DUAL 360 int u_tune360; int u_resolution; #elif (RM_MODEL_360) // EMT SINGLE 360 int u_mode; int u_angle; int u_flip; #if (RM_MODEL_360_PAD) int u_effectiveWidth; #endif // RM_MODEL_360_PAD #if (SUB_MODEL_TB5000) int u_screenWidth; int u_screenHeight; int u_realScreenWidth; #endif // SUB_MODEL_TB5000 int u_clipBound; #endif // MODEL_360 #if (SUPPORT_WIDE_MODE) int u_mode; int u_aspect; #endif // SUPPORT_WIDE_MODE #if(TOP_DOWN_2D_360) int u_whratio; #endif // TOP_DOWN_2D_360 qint32 material_type; QVector u_Texture; GLenum texture_target; VideoFormat video_format; mutable QByteArray planar_frag, packed_frag; mutable QByteArray vert; QVector user_uniforms[ShaderTypeCount]; }; class VideoMaterial; class VideoMaterialPrivate : public DPtrPrivate { public: VideoMaterialPrivate() : update_texure(true) , init_textures_required(true) , bpc(0) , width(0) , height(0) , video_format(VideoFormat::Format_Invalid) , plane1_linesize(0) , effective_tex_width_ratio(1.0) , target(GL_TEXTURE_2D) , dirty(true) , try_pbo(true) { v_texel_size.reserve(4); textures.reserve(4); texture_size.reserve(4); effective_tex_width.reserve(4); internal_format.reserve(4); data_format.reserve(4); data_type.reserve(4); static bool enable_pbo = qgetenv("QTAV_PBO").toInt() > 0; if (try_pbo) try_pbo = enable_pbo; pbo.reserve(4); colorTransform.setOutputColorSpace(ColorSpace_RGB); } ~VideoMaterialPrivate(); bool initPBO(int plane, int size); bool initTexture(GLuint tex, GLint internal_format, GLenum format, GLenum dataType, int width, int height); bool updateTextureParameters(const VideoFormat& fmt); void uploadPlane(int p, bool updateTexture = true); bool ensureResources(); bool ensureTextures(); void setupQuality(); bool update_texure; // reduce upload/map times. true: new frame not bound. false: current frame is bound bool init_textures_required; // e.g. target changed int bpc; int width, height; //avoid accessing frame(need lock) VideoFrame frame; /* * old format. used to check whether we have to update textures. set to current frame's format after textures are updated. * TODO: only VideoMaterial.type() is enough to check and update shader. so remove it */ VideoFormat video_format; QSize plane0Size; // width is in bytes. different alignments may result in different plane 1 linesize even if plane 0 are the same int plane1_linesize; // textures.d in updateTextureParameters() changed. happens in qml. why? quint8 workaround_vector_crash_on_linux[8]; //TODO: remove QVector textures; //texture ids. size is plane count QHash owns_texture; QVector texture_size; QVector effective_tex_width; //without additional width for alignment qreal effective_tex_width_ratio; GLenum target; QVector internal_format; QVector data_format; QVector data_type; bool dirty; ColorTransform colorTransform; bool try_pbo; QVector pbo; QVector2D vec_to8; //TODO: vec3 to support both RG and LA (.rga, vec_to8) QMatrix4x4 channel_map; QVector v_texel_size; QVector v_texture_size; }; } //namespace FAV #endif // QTAV_VideoShader_P_H