Bug 1355763 - Handle UNPACK_ state for ConvertPlanarYCbCr, and reject blits with _SKIP_* for now. - r=daoshengmu
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 12 Apr 2017 09:22:28 -0700
changeset 562195 bbd23665a2d1a5c514b4d2f1f93e3ff46aa74dcc
parent 562194 f0e8fd36b730c776f054d462e0375081288c6ff0
child 562196 c9683ac4e2d1cfed2ae1dc9b76b6501d39278489
push id53981
push userbmo:jgilbert@mozilla.com
push dateThu, 13 Apr 2017 16:16:08 +0000
reviewersdaoshengmu
bugs1355763
milestone55.0a1
Bug 1355763 - Handle UNPACK_ state for ConvertPlanarYCbCr, and reject blits with _SKIP_* for now. - r=daoshengmu MozReview-Commit-ID: JsDF66DwTfZ
dom/canvas/TexUnpackBlob.cpp
gfx/gl/GLBlitHelper.cpp
gfx/gl/ScopedGLHelpers.cpp
gfx/gl/ScopedGLHelpers.h
--- 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;