void DrawBlitProg::Draw(const BaseArgs& args, const YUVArgs* const argsYUV) const { const auto& gl = mParent.mGL; const SaveRestoreCurrentProgram oldProg(gl); gl->fUseProgram(mProg); // -- Mat3 destMatrix; if (args.destRect) { const auto& destRect = args.destRect.value(); destMatrix = SubRectMat3(destRect.X() / args.destSize.width, destRect.Y() / args.destSize.height, destRect.Width() / args.destSize.width, destRect.Height() / args.destSize.height); } else { destMatrix = Mat3::I(); } if (args.yFlip) { // Apply the y-flip matrix before the destMatrix. // That is, flip y=[0-1] to y=[1-0] before we restrict to the destRect. destMatrix.at(2,1) += destMatrix.at(1,1); destMatrix.at(1,1) *= -1.0f; } gl->fUniformMatrix3fv(mLoc_uDestMatrix, 1, false, destMatrix.m); gl->fUniformMatrix3fv(mLoc_uTexMatrix0, 1, false, args.texMatrix0.m); MOZ_ASSERT(bool(argsYUV) == (mLoc_uColorMatrix != -1)); if (argsYUV) { gl->fUniformMatrix3fv(mLoc_uTexMatrix1, 1, false, argsYUV->texMatrix1.m); const auto& colorMatrix = gfxUtils::YuvToRgbMatrix4x4ColumnMajor(argsYUV->colorSpace); float mat4x3[4*3]; switch (mType_uColorMatrix) { case LOCAL_GL_FLOAT_MAT4: gl->fUniformMatrix4fv(mLoc_uColorMatrix, 1, false, colorMatrix); break; case LOCAL_GL_FLOAT_MAT4x3: for (int x = 0; x < 4; x++) { for (int y = 0; y < 3; y++) { mat4x3[3*x+y] = colorMatrix[4*x+y]; } } gl->fUniformMatrix4x3fv(mLoc_uColorMatrix, 1, false, mat4x3); break; default: gfxCriticalError() << "Bad mType_uColorMatrix: " << gfx::hexa(mType_uColorMatrix); } } // -- const ScopedDrawBlitState drawState(gl, args.destSize); GLuint oldVAO; GLint vaa0Enabled; GLint vaa0Size; GLenum vaa0Type; GLint vaa0Normalized; GLsizei vaa0Stride; GLvoid* vaa0Pointer; if (mParent.mQuadVAO) { oldVAO = gl->GetIntAs<GLuint>(LOCAL_GL_VERTEX_ARRAY_BINDING); gl->fBindVertexArray(mParent.mQuadVAO); } else { gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED, &vaa0Enabled); gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE, &vaa0Size); gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE, (GLint*)&vaa0Type); gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &vaa0Normalized); gl->fGetVertexAttribiv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE, (GLint*)&vaa0Stride); gl->fGetVertexAttribPointerv(0, LOCAL_GL_VERTEX_ATTRIB_ARRAY_POINTER, &vaa0Pointer); gl->fEnableVertexAttribArray(0); const ScopedBindArrayBuffer bindVBO(gl, mParent.mQuadVBO); gl->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, false, 0, 0); } gl->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4); if (mParent.mQuadVAO) { gl->fBindVertexArray(oldVAO); } else { if (vaa0Enabled) { gl->fEnableVertexAttribArray(0); } else { gl->fDisableVertexAttribArray(0); } gl->fVertexAttribPointer(0, vaa0Size, vaa0Type, bool(vaa0Normalized), vaa0Stride, vaa0Pointer); } }