Bug 1361574 - Restore texture after creating the video texture; r?sotaro draft
authorKevin Chen <kechen@mozilla.com>
Thu, 25 May 2017 17:42:28 +0800
changeset 589431 1fa69dba3fe6e6887b7ec2974539b41c3aa7062e
parent 589301 2c6289f56812c30254acfdddabcfec1e149c0336
child 631874 86322c574871a0f0e4f89394e68f56a09aab39d6
push id62367
push userbmo:kechen@mozilla.com
push dateTue, 06 Jun 2017 06:46:38 +0000
reviewerssotaro
bugs1361574
milestone55.0a1
Bug 1361574 - Restore texture after creating the video texture; r?sotaro MozReview-Commit-ID: 1XAPVwW8zv3
dom/canvas/CanvasRenderingContext2D.cpp
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -128,16 +128,17 @@
 #include "mozilla/layers/CanvasClient.h"
 
 #undef free // apparently defined by some windows header, clashing with a free()
             // method in SkTypes.h
 #include "SkiaGLGlue.h"
 #ifdef USE_SKIA
 #include "SurfaceTypes.h"
 #include "GLBlitHelper.h"
+#include "ScopedGLHelpers.h"
 #endif
 
 using mozilla::gl::GLContext;
 using mozilla::gl::SkiaGLGlue;
 using mozilla::gl::GLContextProvider;
 
 #ifdef XP_WIN
 #include "gfxWindowsPlatform.h"
@@ -5227,56 +5228,59 @@ CanvasRenderingContext2D::DrawImage(cons
 
     AutoLockImage lockImage(container);
     layers::Image* srcImage = lockImage.GetImage();
     if (!srcImage) {
       aError.Throw(NS_ERROR_NOT_AVAILABLE);
       return;
     }
 
-    gl->MakeCurrent();
-    GLuint videoTexture = 0;
-    gl->fGenTextures(1, &videoTexture);
-    // skiaGL expect upload on drawing, and uses texture 0 for texturing,
-    // so we must active texture 0 and bind the texture for it.
-    gl->fActiveTexture(LOCAL_GL_TEXTURE0);
-    gl->fBindTexture(LOCAL_GL_TEXTURE_2D, videoTexture);
-
-    gl->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGB, srcImage->GetSize().width, srcImage->GetSize().height, 0, LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT_5_6_5, nullptr);
-    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
-    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-
-    const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
-    bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage, srcImage->GetSize(),
-                                                   videoTexture, LOCAL_GL_TEXTURE_2D,
-                                                   destOrigin);
-    if (ok) {
-      NativeSurface texSurf;
-      texSurf.mType = NativeSurfaceType::OPENGL_TEXTURE;
-      texSurf.mFormat = SurfaceFormat::R5G6B5_UINT16;
-      texSurf.mSize.width = srcImage->GetSize().width;
-      texSurf.mSize.height = srcImage->GetSize().height;
-      texSurf.mSurface = (void*)((uintptr_t)videoTexture);
-
-      srcSurf = mTarget->CreateSourceSurfaceFromNativeSurface(texSurf);
-      if (!srcSurf) {
+    {
+      gl->MakeCurrent();
+      GLuint videoTexture = 0;
+      gl->fGenTextures(1, &videoTexture);
+      // skiaGL expect upload on drawing, and uses texture 0 for texturing,
+      // so we must active texture 0 and bind the texture for it.
+      gl->fActiveTexture(LOCAL_GL_TEXTURE0);
+      const gl::ScopedBindTexture scopeBindTexture(gl, videoTexture);
+
+      gl->fTexImage2D(LOCAL_GL_TEXTURE_2D, 0, LOCAL_GL_RGB, srcImage->GetSize().width, srcImage->GetSize().height, 0, LOCAL_GL_RGB, LOCAL_GL_UNSIGNED_SHORT_5_6_5, nullptr);
+      gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+      gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+      gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
+      gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
+
+      const gl::OriginPos destOrigin = gl::OriginPos::TopLeft;
+      bool ok = gl->BlitHelper()->BlitImageToTexture(srcImage, srcImage->GetSize(),
+                                                     videoTexture, LOCAL_GL_TEXTURE_2D,
+                                                     destOrigin);
+      if (ok) {
+        NativeSurface texSurf;
+        texSurf.mType = NativeSurfaceType::OPENGL_TEXTURE;
+        texSurf.mFormat = SurfaceFormat::R5G6B5_UINT16;
+        texSurf.mSize.width = srcImage->GetSize().width;
+        texSurf.mSize.height = srcImage->GetSize().height;
+        texSurf.mSurface = (void*)((uintptr_t)videoTexture);
+
+        srcSurf = mTarget->CreateSourceSurfaceFromNativeSurface(texSurf);
+        if (!srcSurf) {
+          gl->fDeleteTextures(1, &videoTexture);
+        }
+        imgSize.width = srcImage->GetSize().width;
+        imgSize.height = srcImage->GetSize().height;
+
+        int32_t displayWidth = video->VideoWidth();
+        int32_t displayHeight = video->VideoHeight();
+        aSw *= (double)imgSize.width / (double)displayWidth;
+        aSh *= (double)imgSize.height / (double)displayHeight;
+      } else {
         gl->fDeleteTextures(1, &videoTexture);
       }
-      imgSize.width = srcImage->GetSize().width;
-      imgSize.height = srcImage->GetSize().height;
-
-      int32_t displayWidth = video->VideoWidth();
-      int32_t displayHeight = video->VideoHeight();
-      aSw *= (double)imgSize.width / (double)displayWidth;
-      aSh *= (double)imgSize.height / (double)displayHeight;
-    } else {
-      gl->fDeleteTextures(1, &videoTexture);
     }
+
     srcImage = nullptr;
 
     if (mCanvasElement) {
       CanvasUtils::DoDrawImageSecurityCheck(mCanvasElement,
                                             principal, false,
                                             video->GetCORSMode() != CORS_NONE);
     }
   }