Bug 1355763 - Handle UNPACK_ state for ConvertPlanarYCbCr, and reject blits with _SKIP_* for now. - r=daoshengmu
MozReview-Commit-ID: JsDF66DwTfZ
--- a/dom/canvas/TexUnpackBlob.cpp
+++ b/dom/canvas/TexUnpackBlob.cpp
@@ -632,16 +632,24 @@ TexUnpackImage::TexOrSubImage(bool isSub
const char* fallbackReason;
do {
if (mDepth != 1) {
fallbackReason = "depth is not 1";
break;
}
+ if (webgl->mPixelStore_UnpackSkipPixels ||
+ webgl->mPixelStore_UnpackSkipRows ||
+ webgl->mPixelStore_UnpackSkipImages)
+ {
+ fallbackReason = "non-zero UNPACK_SKIP_* not yet supported";
+ break;
+ }
+
const auto fnHasPremultMismatch = [&]() {
if (mSrcAlphaType == gfxAlphaType::Opaque)
return false;
const bool srcIsPremult = (mSrcAlphaType == gfxAlphaType::Premult);
const auto& dstIsPremult = webgl->mPixelStore_PremultiplyAlpha;
if (srcIsPremult == dstIsPremult)
return false;
--- a/gfx/gl/GLBlitHelper.cpp
+++ b/gfx/gl/GLBlitHelper.cpp
@@ -751,19 +751,23 @@ GLBlitHelper::BlitPlanarYCbCrImage(layer
needsAllocation = true;
}
GLint oldTex[3];
for (int i = 0; i < 3; i++) {
mGL->fActiveTexture(LOCAL_GL_TEXTURE0 + i);
mGL->fGetIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &oldTex[i]);
}
- BindAndUploadYUVTexture(Channel_Y, yuvData->mYStride, yuvData->mYSize.height, yuvData->mYChannel, needsAllocation);
- BindAndUploadYUVTexture(Channel_Cb, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCbChannel, needsAllocation);
- BindAndUploadYUVTexture(Channel_Cr, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCrChannel, needsAllocation);
+
+ {
+ const ResetUnpackState reset(mGL);
+ BindAndUploadYUVTexture(Channel_Y, yuvData->mYStride, yuvData->mYSize.height, yuvData->mYChannel, needsAllocation);
+ BindAndUploadYUVTexture(Channel_Cb, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCbChannel, needsAllocation);
+ BindAndUploadYUVTexture(Channel_Cr, yuvData->mCbCrStride, yuvData->mCbCrSize.height, yuvData->mCrChannel, needsAllocation);
+ }
if (needsAllocation) {
mGL->fUniform2f(mYTexScaleLoc, (float)yuvData->mYSize.width/yuvData->mYStride, 1.0f);
mGL->fUniform2f(mCbCrTexScaleLoc, (float)yuvData->mCbCrSize.width/yuvData->mCbCrStride, 1.0f);
}
const auto& yuvToRgb = gfxUtils::YuvToRgbMatrix3x3ColumnMajor(yuvData->mYUVColorSpace);
mGL->fUniformMatrix3fv(mYuvColorMatrixLoc, 1, 0, yuvToRgb);
@@ -863,23 +867,18 @@ GLBlitHelper::BlitImageToFramebuffer(lay
const bool needsYFlip = (srcOrigin != destOrigin);
mGL->fUniform1f(mYFlipLoc, needsYFlip ? (float)1.0 : (float)0.0);
ScopedBindFramebuffer boundFB(mGL, destFB);
mGL->fColorMask(LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE, LOCAL_GL_TRUE);
mGL->fViewport(0, 0, destSize.width, destSize.height);
switch (type) {
- case ConvertPlanarYCbCr: {
- const auto saved = mGL->GetIntAs<GLint>(LOCAL_GL_UNPACK_ALIGNMENT);
- mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 1);
- const auto ret = BlitPlanarYCbCrImage(static_cast<PlanarYCbCrImage*>(srcImage));
- mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, saved);
- return ret;
- }
+ case ConvertPlanarYCbCr:
+ return BlitPlanarYCbCrImage(static_cast<PlanarYCbCrImage*>(srcImage));
#ifdef MOZ_WIDGET_ANDROID
case ConvertSurfaceTexture:
return BlitSurfaceTextureImage(static_cast<layers::SurfaceTextureImage*>(srcImage));
case ConvertEGLImage:
return BlitEGLImageImage(static_cast<layers::EGLImageImage*>(srcImage));
#endif
--- a/gfx/gl/ScopedGLHelpers.cpp
+++ b/gfx/gl/ScopedGLHelpers.cpp
@@ -526,16 +526,62 @@ ScopedPackState::UnwrapImpl()
mGL->fBindBuffer(LOCAL_GL_PIXEL_PACK_BUFFER, mPixelBuffer);
mGL->fPixelStorei(LOCAL_GL_PACK_ROW_LENGTH, mRowLength);
mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_PIXELS, mSkipPixels);
mGL->fPixelStorei(LOCAL_GL_PACK_SKIP_ROWS, mSkipRows);
}
////////////////////////////////////////////////////////////////////////
+// ResetUnpackState
+
+ResetUnpackState::ResetUnpackState(GLContext* gl)
+ : ScopedGLWrapper<ResetUnpackState>(gl)
+{
+ const auto fnReset = [&](GLenum pname, GLuint val, GLuint* const out_old) {
+ mGL->GetUIntegerv(pname, out_old);
+ if (*out_old != val) {
+ mGL->fPixelStorei(pname, val);
+ }
+ };
+
+ // Default is 4, but 1 is more useful.
+ fnReset(LOCAL_GL_UNPACK_ALIGNMENT, 1, &mAlignment);
+
+ if (!mGL->HasPBOState())
+ return;
+
+ mGL->GetUIntegerv(LOCAL_GL_PIXEL_UNPACK_BUFFER_BINDING, &mPBO);
+ if (mPBO != 0) mGL->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
+
+ fnReset(LOCAL_GL_UNPACK_ROW_LENGTH , 0, &mRowLength);
+ fnReset(LOCAL_GL_UNPACK_IMAGE_HEIGHT, 0, &mImageHeight);
+ fnReset(LOCAL_GL_UNPACK_SKIP_PIXELS , 0, &mSkipPixels);
+ fnReset(LOCAL_GL_UNPACK_SKIP_ROWS , 0, &mSkipRows);
+ fnReset(LOCAL_GL_UNPACK_SKIP_IMAGES , 0, &mSkipImages);
+}
+
+void
+ResetUnpackState::UnwrapImpl()
+{
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, mAlignment);
+
+ if (!mGL->HasPBOState())
+ return;
+
+ mGL->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPBO);
+
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, mRowLength);
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_IMAGE_HEIGHT, mImageHeight);
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_SKIP_PIXELS, mSkipPixels);
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_SKIP_ROWS, mSkipRows);
+ mGL->fPixelStorei(LOCAL_GL_UNPACK_SKIP_IMAGES, mSkipImages);
+}
+
+////////////////////////////////////////////////////////////////////////
// ScopedBindPBO
static GLuint
GetPBOBinding(GLContext* gl, GLenum target)
{
if (!gl->HasPBOState())
return 0;
--- a/gfx/gl/ScopedGLHelpers.h
+++ b/gfx/gl/ScopedGLHelpers.h
@@ -357,16 +357,38 @@ protected:
public:
explicit ScopedPackState(GLContext* gl);
protected:
void UnwrapImpl();
};
+struct ResetUnpackState
+ : public ScopedGLWrapper<ResetUnpackState>
+{
+ friend struct ScopedGLWrapper<ResetUnpackState>;
+
+protected:
+ GLuint mAlignment;
+
+ GLuint mPBO;
+ GLuint mRowLength;
+ GLuint mImageHeight;
+ GLuint mSkipPixels;
+ GLuint mSkipRows;
+ GLuint mSkipImages;
+
+public:
+ explicit ResetUnpackState(GLContext* gl);
+
+protected:
+ void UnwrapImpl();
+};
+
struct ScopedBindPBO final
: public ScopedGLWrapper<ScopedBindPBO>
{
friend struct ScopedGLWrapper<ScopedBindPBO>;
protected:
const GLenum mTarget;
const GLuint mPBO;