virtual void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) { Q_UNUSED(oldMaterial); VideoMaterial *material = static_cast<VideoMaterial *>(newMaterial); if (m_id_rgbTexture > 0) { program()->setUniformValue(m_id_rgbTexture, 0); } else { program()->setUniformValue(m_id_yTexture, 0); program()->setUniformValue(m_id_uTexture, 1); program()->setUniformValue(m_id_vTexture, 2); } if (state.isOpacityDirty()) { material->setFlag(QSGMaterial::Blending, qFuzzyCompare(state.opacity(), 1.0f) ? false : true); program()->setUniformValue(m_id_opacity, GLfloat(state.opacity())); } if (state.isMatrixDirty()) program()->setUniformValue(m_id_matrix, state.combinedMatrix()); program()->setUniformValue(m_id_colorMatrix, material->m_colorMatrix); material->bind(); }
void OpenGLVideoPrivate::bindAttributes(VideoShader* shader, const QRectF &t, const QRectF &r) { // also check size change for normalizedROI computation if roi is not normalized const bool roi_changed = valiad_tex_width != material->validTextureWidth() || roi != r || video_size != material->frameSize(); const int tc = shader->textureLocationCount(); if (roi_changed) { roi = r; valiad_tex_width = material->validTextureWidth(); video_size = material->frameSize(); } if (tex_target != shader->textureTarget()) { tex_target = shader->textureTarget(); update_geo = true; } QRectF& target_rect = rect; if (target.isValid()) { if (roi_changed || target != t) { target = t; update_geo = true; //target_rect = target (if valid). // relate to gvf bug? } } else { if (roi_changed) { update_geo = true; } } if (!update_geo) { gr.bindBuffers(&geometry); return; } //qDebug("updating geometry..."); // setTextureCount may change the vertex data. Call it before setRect() geometry.setTextureCount(shader->textureTarget() == GL_TEXTURE_RECTANGLE ? tc : 1); geometry.setRect(target_rect, material->mapToTexture(0, roi)); if (shader->textureTarget() == GL_TEXTURE_RECTANGLE) { for (int i = 1; i < tc; ++i) { // tc can > planes, but that will compute chroma plane geometry.setTextureRect(material->mapToTexture(i, roi), i); } } update_geo = false; gr.updateBuffers(&geometry); gr.bindBuffers(&geometry); }
VideoMaterial *VideoMaterial::create(const BufferFormat & format) { VideoMaterial *material = NULL; switch (format.videoFormat()) { // BGRx case GST_VIDEO_FORMAT_BGRx: case GST_VIDEO_FORMAT_BGRA: material = new VideoMaterialImpl<qtvideosink_glsl_bgrxFragmentShader>; material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); break; case GST_VIDEO_FORMAT_BGR: material = new VideoMaterialImpl<qtvideosink_glsl_bgrxFragmentShader>; material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); break; // xRGB case GST_VIDEO_FORMAT_xRGB: case GST_VIDEO_FORMAT_ARGB: case GST_VIDEO_FORMAT_AYUV: material = new VideoMaterialImpl<qtvideosink_glsl_xrgbFragmentShader>; material->initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize()); break; // RGBx case GST_VIDEO_FORMAT_RGB: case GST_VIDEO_FORMAT_v308: material = new VideoMaterialImpl<qtvideosink_glsl_rgbxFragmentShader>; material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize()); break; case GST_VIDEO_FORMAT_RGB16: material = new VideoMaterialImpl<qtvideosink_glsl_rgbxFragmentShader>; material->initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize()); break; // YUV 420 planar case GST_VIDEO_FORMAT_I420: case GST_VIDEO_FORMAT_YV12: material = new VideoMaterialImpl<qtvideosink_glsl_yuvPlanarFragmentShader>; material->initYuv420PTextureInfo( (format.videoFormat() == GST_VIDEO_FORMAT_YV12) /* uvSwapped */, format.frameSize()); break; default: Q_ASSERT(false); break; } material->init(format.colorMatrix()); return material; }
void OpenGLVideoPrivate::bindAttributes(VideoShader* shader, const QRectF &t, const QRectF &r) { const bool tex_rect = shader->textureTarget() == GL_TEXTURE_RECTANGLE; // also check size change for normalizedROI computation if roi is not normalized const bool roi_changed = valiad_tex_width != material->validTextureWidth() || roi != r || video_size != material->frameSize(); const int tc = shader->textureLocationCount(); if (roi_changed) { roi = r; valiad_tex_width = material->validTextureWidth(); video_size = material->frameSize(); } if (tex_target != shader->textureTarget()) { tex_target = shader->textureTarget(); update_geo = true; } QRectF& target_rect = rect; if (target.isValid()) { if (roi_changed || target != t) { target = t; update_geo = true; } } else { if (roi_changed) { update_geo = true; } } if (!update_geo) goto end; //qDebug("updating geometry..."); geometry.setRect(target_rect, material->mapToTexture(0, roi)); if (tex_rect) { geometry.setTextureCount(tc); for (int i = 1; i < tc; ++i) { // tc can > planes, but that will compute chroma plane geometry.setTextureRect(material->mapToTexture(i, roi), i); } } update_geo = false; if (!try_vbo) goto end; { //VAO scope BEGIN #if QT_VAO if (try_vao) { //qDebug("updating vao..."); if (!vao.isCreated()) { if (!vao.create()) { try_vao = false; qDebug("VAO is not supported"); } } } QOpenGLVertexArrayObject::Binder vao_bind(&vao); Q_UNUSED(vao_bind); #endif if (!vbo.isCreated()) { if (!vbo.create()) { try_vbo = false; // not supported by OpenGL try_vao = false; // also disable VAO. destroy? qWarning("VBO is not supported"); goto end; } } //qDebug("updating vbo..."); vbo.bind(); //check here vbo.allocate(geometry.data(), geometry.size()); #if QT_VAO if (try_vao) { shader->program()->setAttributeBuffer(0, GL_FLOAT, 0, geometry.tupleSize(), geometry.stride()); shader->program()->setAttributeBuffer(1, GL_FLOAT, geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride()); if (tex_rect) { for (int i = 1; i < tc; ++i) { shader->program()->setAttributeBuffer(i + 1, GL_FLOAT, i*geometry.textureSize() + geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride()); } } char const *const *attr = shader->attributeNames(); for (int i = 0; attr[i]; ++i) { shader->program()->enableAttributeArray(i); //TODO: in setActiveShader } } #endif vbo.release(); } //VAO scope END end: #if QT_VAO if (try_vao && vao.isCreated()) { vao.bind(); return; } #endif if (try_vbo && vbo.isCreated()) { vbo.bind(); shader->program()->setAttributeBuffer(0, GL_FLOAT, 0, geometry.tupleSize(), geometry.stride()); shader->program()->setAttributeBuffer(1, GL_FLOAT, geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride()); if (tex_rect) { for (int i = 1; i < tc; ++i) { shader->program()->setAttributeBuffer(i + 1, GL_FLOAT, i*geometry.textureSize() + geometry.tupleSize()*sizeof(float), geometry.tupleSize(), geometry.stride()); } } } else { shader->program()->setAttributeArray(0, GL_FLOAT, geometry.data(0), geometry.tupleSize(), geometry.stride()); shader->program()->setAttributeArray(1, GL_FLOAT, geometry.data(1), geometry.tupleSize(), geometry.stride()); if (tex_rect) { for (int i = 1; i < tc; ++i) { shader->program()->setAttributeArray(i + 1, GL_FLOAT, geometry.data(1), i*geometry.textureSize() + geometry.tupleSize(), geometry.stride()); } } } char const *const *attr = shader->attributeNames(); for (int i = 0; attr[i]; ++i) { shader->program()->enableAttributeArray(i); //TODO: in setActiveShader } }