Bug 971914 - Make TextureSourceOGL responsible for tracking filter state. r=nical
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 13 Mar 2014 13:37:17 +1300
changeset 190494 badf9a3d3f79dae758271aee74fe81cb52cb0af4
parent 190493 ceb23e4d75545648b09456665cce9846b0fadbc0
child 190495 86fad085d4b16e8840c8b7344703f6542b12b9a7
push id3503
push userraliiev@mozilla.com
push dateMon, 28 Apr 2014 18:51:11 +0000
treeherdermozilla-beta@c95ac01e332e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs971914
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 971914 - Make TextureSourceOGL responsible for tracking filter state. r=nical
gfx/layers/LayerScope.cpp
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/GrallocTextureHost.cpp
gfx/layers/opengl/GrallocTextureHost.h
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
gfx/layers/opengl/TextureHostOGL.cpp
gfx/layers/opengl/TextureHostOGL.h
gfx/layers/opengl/X11TextureSourceOGL.cpp
gfx/layers/opengl/X11TextureSourceOGL.h
--- a/gfx/layers/LayerScope.cpp
+++ b/gfx/layers/LayerScope.cpp
@@ -700,17 +700,17 @@ SendTextureSource(GLContext* aGLContext,
                   TextureSourceOGL* aSource,
                   bool aFlipY)
 {
     GLenum textureTarget = aSource->GetTextureTarget();
     ShaderConfigOGL config = ShaderConfigFromTargetAndFormat(textureTarget,
                                                              aSource->GetFormat());
     int shaderConfig = config.mFeatures;
 
-    aSource->BindTexture(LOCAL_GL_TEXTURE0);
+    aSource->BindTexture(LOCAL_GL_TEXTURE0, gfx::Filter::LINEAR);
 
     GLuint textureId = 0;
     // This is horrid hack. It assumes that aGLContext matches the context
     // aSource has bound to.
     if (textureTarget == LOCAL_GL_TEXTURE_2D) {
         aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &textureId);
     } else if (textureTarget == LOCAL_GL_TEXTURE_EXTERNAL) {
         aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &textureId);
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -65,17 +65,17 @@ static inline IntSize ns2gfxSize(const n
   return IntSize(s.width, s.height);
 }
 
 static void
 BindMaskForProgram(ShaderProgramOGL* aProgram, TextureSourceOGL* aSourceMask,
                    GLenum aTexUnit, const gfx::Matrix4x4& aTransform)
 {
   MOZ_ASSERT(LOCAL_GL_TEXTURE0 <= aTexUnit && aTexUnit <= LOCAL_GL_TEXTURE31);
-  aSourceMask->BindTexture(aTexUnit);
+  aSourceMask->BindTexture(aTexUnit, gfx::Filter::LINEAR);
   aProgram->SetMaskTextureUnit(aTexUnit - LOCAL_GL_TEXTURE0);
   aProgram->SetMaskLayerTransform(aTransform);
 }
 
 // Draw the given quads with the already selected shader. Texture coordinates
 // are supplied if the shader requires them.
 static void
 DrawQuads(GLContext *aGLContext,
@@ -875,30 +875,16 @@ CompositorOGL::DrawLines(const std::vect
     const gfx::Point& p1 = aLines[i];
     const gfx::Point& p2 = aLines[i+1];
     DrawQuadInternal(Rect(p1.x, p2.y, p2.x - p1.x, p1.y - p2.y),
                      aClipRect, effects, aOpacity, aTransform,
                      LOCAL_GL_LINE_STRIP);
   }
 }
 
-/**
- * Applies aFilter to the texture currently bound to aTarget.
- */
-void ApplyFilterToBoundTexture(GLContext* aGL,
-                               GraphicsFilter aFilter,
-                               GLuint aTarget = LOCAL_GL_TEXTURE_2D)
-{
-  GLenum filter =
-    (aFilter == GraphicsFilter::FILTER_NEAREST ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR);
-
-    aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, filter);
-    aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, filter);
-}
-
 void
 CompositorOGL::DrawQuadInternal(const Rect& aRect,
                                 const Rect& aClipRect,
                                 const EffectChain &aEffectChain,
                                 Float aOpacity,
                                 const gfx::Matrix4x4 &aTransform,
                                 GLuint aDrawMode)
 {
@@ -1007,36 +993,33 @@ CompositorOGL::DrawQuadInternal(const Re
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       TextureSource *source = texturedEffect->mTexture;
 
       if (!texturedEffect->mPremultiplied) {
         mGLContext->fBlendFuncSeparate(LOCAL_GL_SRC_ALPHA, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                        LOCAL_GL_ONE, LOCAL_GL_ONE);
       }
 
-      source->AsSourceOGL()->BindTexture(LOCAL_GL_TEXTURE0);
-
-      GraphicsFilter filter = ThebesFilter(texturedEffect->mFilter);
+      gfx::Filter filter = texturedEffect->mFilter;
       gfx3DMatrix textureTransform;
       gfx::To3DMatrix(source->AsSourceOGL()->GetTextureTransform(), textureTransform);
 
 #ifdef MOZ_WIDGET_ANDROID
       gfxMatrix textureTransform2D;
-      if (filter != GraphicsFilter::FILTER_NEAREST &&
+      if (filter != gfx::Filter::POINT &&
           aTransform.Is2DIntegerTranslation() &&
           textureTransform.Is2D(&textureTransform2D) &&
           textureTransform2D.HasOnlyIntegerTranslation()) {
         // On Android we encounter small resampling errors in what should be
         // pixel-aligned compositing operations. This works around them. This
         // code should not be needed!
-        filter = GraphicsFilter::FILTER_NEAREST;
+        filter = gfx::Filter::POINT;
       }
 #endif
-      ApplyFilterToBoundTexture(mGLContext, filter,
-                                source->AsSourceOGL()->GetTextureTarget());
+      source->AsSourceOGL()->BindTexture(LOCAL_GL_TEXTURE0, filter);
 
       program->SetTextureUnit(0);
 
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1, maskQuadTransform);
       }
 
       BindAndDrawQuadWithTextureRect(program, textureTransform,
@@ -1057,24 +1040,19 @@ CompositorOGL::DrawQuadInternal(const Re
       TextureSourceOGL* sourceCb = sourceYCbCr->GetSubSource(Cb)->AsSourceOGL();
       TextureSourceOGL* sourceCr = sourceYCbCr->GetSubSource(Cr)->AsSourceOGL();
 
       if (!sourceY && !sourceCb && !sourceCr) {
         NS_WARNING("Invalid layer texture.");
         return;
       }
 
-      GraphicsFilter filter = ThebesFilter(effectYCbCr->mFilter);
-
-      sourceY->BindTexture(LOCAL_GL_TEXTURE0);
-      ApplyFilterToBoundTexture(mGLContext, filter);
-      sourceCb->BindTexture(LOCAL_GL_TEXTURE1);
-      ApplyFilterToBoundTexture(mGLContext, filter);
-      sourceCr->BindTexture(LOCAL_GL_TEXTURE2);
-      ApplyFilterToBoundTexture(mGLContext, filter);
+      sourceY->BindTexture(LOCAL_GL_TEXTURE0, effectYCbCr->mFilter);
+      sourceCb->BindTexture(LOCAL_GL_TEXTURE1, effectYCbCr->mFilter);
+      sourceCr->BindTexture(LOCAL_GL_TEXTURE2, effectYCbCr->mFilter);
 
       program->SetYCbCrTextureUnits(Y, Cb, Cr);
 
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE3, maskQuadTransform);
       }
       BindAndDrawQuadWithTextureRect(program,
                                      gfx3DMatrix(),
@@ -1089,17 +1067,17 @@ CompositorOGL::DrawQuadInternal(const Re
         = static_cast<CompositingRenderTargetOGL*>(effectRenderTarget->mRenderTarget.get());
 
       surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget);
 
       program->SetTextureTransform(Matrix4x4());
       program->SetTextureUnit(0);
 
       if (maskType != MaskNone) {
-        sourceMask->BindTexture(LOCAL_GL_TEXTURE1);
+        sourceMask->BindTexture(LOCAL_GL_TEXTURE1, gfx::Filter::LINEAR);
         program->SetMaskTextureUnit(1);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
 
       if (config.mFeatures & ENABLE_TEXTURE_RECT) {
         // 2DRect case, get the multiplier right for a sampler2DRect
         program->SetTexCoordMultiplier(aRect.width, aRect.height);
       }
@@ -1118,18 +1096,18 @@ CompositorOGL::DrawQuadInternal(const Re
       TextureSourceOGL* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceOGL();
 
       if (!sourceOnBlack->IsValid() ||
           !sourceOnWhite->IsValid()) {
         NS_WARNING("Invalid layer texture for component alpha");
         return;
       }
 
-      sourceOnBlack->BindTexture(LOCAL_GL_TEXTURE0);
-      sourceOnWhite->BindTexture(LOCAL_GL_TEXTURE1);
+      sourceOnBlack->BindTexture(LOCAL_GL_TEXTURE0, effectComponentAlpha->mFilter);
+      sourceOnWhite->BindTexture(LOCAL_GL_TEXTURE1, effectComponentAlpha->mFilter);
 
       program->SetBlackTextureUnit(0);
       program->SetWhiteTextureUnit(1);
       program->SetTextureTransform(gfx::Matrix4x4());
 
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2, maskQuadTransform);
       }
--- a/gfx/layers/opengl/GrallocTextureHost.cpp
+++ b/gfx/layers/opengl/GrallocTextureHost.cpp
@@ -99,31 +99,31 @@ GrallocTextureSourceOGL::GrallocTextureS
 
 GrallocTextureSourceOGL::~GrallocTextureSourceOGL()
 {
   DeallocateDeviceData();
   mCompositor = nullptr;
 }
 
 void
-GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit)
+GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   MOZ_ASSERT(gl());
   if (!IsValid()) {
     return;
   }
   gl()->MakeCurrent();
 
   GLuint tex = GetGLTexture();
   GLuint textureTarget = GetTextureTarget();
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(textureTarget, tex);
 
-  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
+  ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
 }
 
 void GrallocTextureSourceOGL::Lock()
 {
   /*
    * The job of this function is to ensure that the texture is tied to the
    * android::GraphicBuffer, so that texturing will source the GraphicBuffer.
    *
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -25,17 +25,17 @@ public:
   GrallocTextureSourceOGL(CompositorOGL* aCompositor,
                           android::GraphicBuffer* aGraphicBuffer,
                           gfx::SurfaceFormat aFormat);
 
   virtual ~GrallocTextureSourceOGL();
 
   virtual bool IsValid() const MOZ_OVERRIDE;
 
-  virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
+  virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE;
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
 
   virtual GLenum GetTextureTarget() const MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.cpp
@@ -79,28 +79,28 @@ MacIOSurfaceTextureSourceOGL::GetSize() 
 
 gfx::SurfaceFormat
 MacIOSurfaceTextureSourceOGL::GetFormat() const
 {
   return mSurface->HasAlpha() ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8X8;
 }
 
 void
-MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit)
+MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   if (!gl()) {
     NS_WARNING("Trying to bind a texture without a GLContext");
     return;
   }
   GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, tex);
   mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl())->GetCGLContext());
-  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
+  ApplyFilterToBoundTexture(gl(), aFilter, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
 }
 
 void
 MacIOSurfaceTextureSourceOGL::SetCompositor(Compositor* aCompositor)
 {
   mCompositor = static_cast<CompositorOGL*>(aCompositor);
 }
 
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
@@ -24,17 +24,17 @@ class MacIOSurfaceTextureSourceOGL : pub
 {
 public:
   MacIOSurfaceTextureSourceOGL(CompositorOGL* aCompositor,
                                MacIOSurface* aSurface);
   virtual ~MacIOSurfaceTextureSourceOGL();
 
   virtual TextureSourceOGL* AsSourceOGL() { return this; }
 
-  virtual void BindTexture(GLenum activetex) MOZ_OVERRIDE;
+  virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE;
 
   virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
 
   virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_RECTANGLE_ARB; }
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -241,16 +241,17 @@ TextureImageTextureSourceOGL::Update(gfx
       // See bug 893300 (tracks the implementation of ContentHost for new textures).
       mTexImage = CreateTextureImage(mGL,
                                      size,
                                      gfx::ContentForFormat(aSurface->GetFormat()),
                                      WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT),
                                      FlagsToGLFlags(mFlags),
                                      SurfaceFormatToImageFormat(aSurface->GetFormat()));
     }
+    ClearCachedFilter();
   }
 
   mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
 
   if (mTexImage->InUpdate()) {
     mTexImage->EndUpdate();
   }
   return true;
@@ -288,21 +289,22 @@ TextureImageTextureSourceOGL::GetFormat(
 }
 
 nsIntRect TextureImageTextureSourceOGL::GetTileRect()
 {
   return ThebesIntRect(mTexImage->GetTileRect());
 }
 
 void
-TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit)
+TextureImageTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   MOZ_ASSERT(mTexImage,
     "Trying to bind a TextureSource that does not have an underlying GL texture.");
   mTexImage->BindTexture(aTextureUnit);
+  SetFilter(mGL, aFilter);
 }
 
 SharedTextureSourceOGL::SharedTextureSourceOGL(CompositorOGL* aCompositor,
                                                gl::SharedTextureHandle aHandle,
                                                gfx::SurfaceFormat aFormat,
                                                GLenum aTarget,
                                                GLenum aWrapMode,
                                                SharedTextureShareType aShareType,
@@ -312,30 +314,31 @@ SharedTextureSourceOGL::SharedTextureSou
   , mSharedHandle(aHandle)
   , mFormat(aFormat)
   , mShareType(aShareType)
   , mTextureTarget(aTarget)
   , mWrapMode(aWrapMode)
 {}
 
 void
-SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit)
+SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   if (!gl()) {
     NS_WARNING("Trying to bind a texture without a GLContext");
     return;
   }
   GLuint tex = mCompositor->GetTemporaryTexture(aTextureUnit);
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(mTextureTarget, tex);
   if (!AttachSharedHandle(gl(), mShareType, mSharedHandle)) {
     NS_ERROR("Failed to bind shared texture handle");
     return;
   }
+  ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
 }
 
 void
 SharedTextureSourceOGL::DetachSharedHandle()
 {
   if (!gl()) {
     return;
   }
@@ -447,21 +450,22 @@ SharedTextureHostOGL::SetCompositor(Comp
 gfx::SurfaceFormat
 SharedTextureHostOGL::GetFormat() const
 {
   MOZ_ASSERT(mTextureSource);
   return mTextureSource->GetFormat();
 }
 
 void
-StreamTextureSourceOGL::BindTexture(GLenum activetex)
+StreamTextureSourceOGL::BindTexture(GLenum activetex, gfx::Filter aFilter)
 {
   MOZ_ASSERT(gl());
   gl()->fActiveTexture(activetex);
   gl()->fBindTexture(mTextureTarget, mTextureHandle);
+  SetFilter(gl(), aFilter);
 }
 
 bool
 StreamTextureSourceOGL::RetrieveTextureFromStream()
 {
   gl()->MakeCurrent();
 
   SharedSurface* sharedSurf = mStream->SwapConsumer();
@@ -533,16 +537,18 @@ StreamTextureSourceOGL::RetrieveTextureF
   gl()->fBindTexture(mTextureTarget, mTextureHandle);
   gl()->fTexParameteri(mTextureTarget,
                       LOCAL_GL_TEXTURE_WRAP_S,
                       LOCAL_GL_CLAMP_TO_EDGE);
   gl()->fTexParameteri(mTextureTarget,
                       LOCAL_GL_TEXTURE_WRAP_T,
                       LOCAL_GL_CLAMP_TO_EDGE);
 
+  ClearCachedFilter();
+
   return true;
 }
 
 void
 StreamTextureSourceOGL::DeallocateDeviceData()
 {
   if (mUploadTexture) {
     MOZ_ASSERT(gl());
@@ -765,20 +771,21 @@ TextureImageDeprecatedTextureHostOGL::Lo
 }
 
 TiledDeprecatedTextureHostOGL::~TiledDeprecatedTextureHostOGL()
 {
   DeleteTextures();
 }
 
 void
-TiledDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit)
+TiledDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   mGL->fActiveTexture(aTextureUnit);
   mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle);
+  SetFilter(mGL, aFilter);
 }
 
 static void
 GetFormatAndTileForImageFormat(gfxImageFormat aFormat,
                                GLenum& aOutFormat,
                                GLenum& aOutType)
 {
   if (aFormat == gfxImageFormat::RGB16_565) {
@@ -830,20 +837,19 @@ TiledDeprecatedTextureHostOGL::Update(gf
   if (!mGL->MakeCurrent()) {
     return;
   }
 
   if (aFlags & TEXTURE_NEW_TILE) {
     SetFlags(aFlags);
     mGL->fGenTextures(1, &mTextureHandle);
     mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle);
-    mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-    mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
     mGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+    ClearCachedFilter();
   } else {
     mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mTextureHandle);
     // We're re-using a texture, but the format may change. Update the memory
     // reporter with a free and alloc (below) using the old and new formats.
     gl::GfxTexturesReporter::UpdateAmount(gl::GfxTexturesReporter::MemoryFreed,
                                           mGLFormat, GetTileType(),
                                           TILEDLAYERBUFFER_TILE_SIZE);
   }
@@ -1047,17 +1053,17 @@ GrallocDeprecatedTextureHostOGL::SwapTex
 }
 
 gl::GLContext*
 GrallocDeprecatedTextureHostOGL::gl() const
 {
   return mCompositor ? mCompositor->gl() : nullptr;
 }
 
-void GrallocDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit)
+void GrallocDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   PROFILER_LABEL("Gralloc", "BindTexture");
   /*
    * The job of this function is to ensure that the texture is tied to the
    * android::GraphicBuffer, so that texturing will source the GraphicBuffer.
    *
    * To this effect we create an EGLImage wrapping this GraphicBuffer,
    * using CreateEGLImageForNativeBuffer, and then we tie this EGLImage to our
@@ -1070,16 +1076,17 @@ void GrallocDeprecatedTextureHostOGL::Bi
   if (!gl()->MakeCurrent()) {
     return;
   }
 
   GLuint tex = GetGLTexture();
 
   gl()->fActiveTexture(aTextureUnit);
   gl()->fBindTexture(mTextureTarget, tex);
+  ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
 }
 
 bool
 GrallocDeprecatedTextureHostOGL::IsValid() const
 {
   return !!gl() && !!mGraphicBuffer.get();
 }
 
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -72,16 +72,27 @@ public:
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
   virtual void ClearData() MOZ_OVERRIDE;
   gl::GLContext* gl() const;
 protected:
   RefPtr<CompositorOGL> mCompositor;
 };
 
+inline void ApplyFilterToBoundTexture(gl::GLContext* aGL,
+                                      gfx::Filter aFilter,
+                                      GLuint aTarget = LOCAL_GL_TEXTURE_2D)
+{
+  GLenum filter =
+    (aFilter == gfx::Filter::POINT ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR);
+
+  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, filter);
+  aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, filter);
+}
+
 /*
  * TextureHost implementations for the OpenGL backend.
  *
  * Note that it is important to be careful about the ownership model with
  * the OpenGL backend, due to some widget limitation on Linux: before
  * the nsBaseWidget associated with our OpenGL context has been completely
  * deleted, every resource belonging to the OpenGL context MUST have been
  * released. At the moment the teardown sequence happens in the middle of
@@ -94,31 +105,52 @@ protected:
 
 /**
  * TextureSourceOGL provides the necessary API for CompositorOGL to composite
  * a TextureSource.
  */
 class TextureSourceOGL
 {
 public:
+  TextureSourceOGL()
+    : mHasCachedFilter(false)
+  {}
+
   virtual bool IsValid() const = 0;
 
-  virtual void BindTexture(GLenum aTextureUnit) = 0;
+  virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) = 0;
 
   virtual gfx::IntSize GetSize() const = 0;
 
   virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; }
 
   virtual gfx::SurfaceFormat GetFormat() const = 0;
 
   virtual GLenum GetWrapMode() const = 0;
 
   virtual gfx::Matrix4x4 GetTextureTransform() { return gfx::Matrix4x4(); }
 
   virtual TextureImageDeprecatedTextureHostOGL* AsTextureImageDeprecatedTextureHost() { return nullptr; }
+
+  void SetFilter(gl::GLContext* aGL, gfx::Filter aFilter)
+  {
+    if (mHasCachedFilter &&
+        mCachedFilter == aFilter) {
+      return;
+    }
+    mHasCachedFilter = true;
+    mCachedFilter = aFilter;
+    ApplyFilterToBoundTexture(aGL, aFilter, GetTextureTarget());
+  }
+
+  void ClearCachedFilter() { mHasCachedFilter = false; }
+
+private:
+  gfx::Filter mCachedFilter;
+  bool mHasCachedFilter;
 };
 
 /**
  * TextureHostOGL provides the necessary API for platform specific composition.
  */
 class TextureHostOGL
 {
 public:
@@ -171,17 +203,17 @@ public:
   virtual void DeallocateDeviceData() MOZ_OVERRIDE
   {
     mTexImage = nullptr;
     SetUpdateSerial(0);
   }
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
 
-  virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
+  virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE;
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
 
   virtual bool IsValid() const MOZ_OVERRIDE { return !!mTexImage; }
 
   virtual void SetCompositor(Compositor* aCompositor) MOZ_OVERRIDE;
@@ -244,17 +276,17 @@ public:
                          gfx::SurfaceFormat aFormat,
                          GLenum aTarget,
                          GLenum aWrapMode,
                          SharedTextureShareType aShareType,
                          gfx::IntSize aSize);
 
   virtual TextureSourceOGL* AsSourceOGL() { return this; }
 
-  virtual void BindTexture(GLenum activetex) MOZ_OVERRIDE;
+  virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE;
 
   virtual bool IsValid() const MOZ_OVERRIDE;
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
 
   virtual gfx::Matrix4x4 GetTextureTransform() MOZ_OVERRIDE;
@@ -357,17 +389,17 @@ public:
 
   ~StreamTextureSourceOGL()
   {
     MOZ_COUNT_DTOR(StreamTextureSourceOGL);
   }
 
   virtual TextureSourceOGL* AsSourceOGL() { return this; }
 
-  virtual void BindTexture(GLenum activetex) MOZ_OVERRIDE;
+  virtual void BindTexture(GLenum activetex, gfx::Filter aFilter) MOZ_OVERRIDE;
 
   virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); }
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
 
   virtual GLenum GetTextureTarget() const { return mTextureTarget; }
@@ -490,17 +522,17 @@ public:
     return !!mTexture;
   }
 
   virtual bool Lock() MOZ_OVERRIDE;
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 
   // textureSource
-  void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE
+  void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE
   {
     mTexture->BindTexture(aTextureUnit);
   }
 
   gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   GLenum GetWrapMode() const MOZ_OVERRIDE
   {
@@ -580,17 +612,17 @@ public:
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE
   {
     return DeprecatedTextureHost::GetFormat();
   }
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
   virtual bool IsValid() const MOZ_OVERRIDE { return true; }
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
-  virtual void BindTexture(GLenum aTextureUnit);
+  virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter);
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE
   {
     return mSize;
   }
 
   virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
                                 nsIntRegion* aRegion = nullptr)
   { MOZ_ASSERT(false, "Tiles should not use this path"); }
@@ -662,17 +694,17 @@ public:
   }
 
   bool IsValid() const MOZ_OVERRIDE;
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 
   virtual const char* Name() { return "GrallocDeprecatedTextureHostOGL"; }
 
-  void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
+  void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE;
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE
   {
     return this;
   }
 
   // only overridden for hacky fix in gecko 23 for bug 862324
   // see bug 865908 about fixing this.
--- a/gfx/layers/opengl/X11TextureSourceOGL.cpp
+++ b/gfx/layers/opengl/X11TextureSourceOGL.cpp
@@ -34,32 +34,32 @@ X11TextureSourceOGL::DeallocateDeviceDat
       gl::sGLXLibrary.ReleaseTexImage(mSurface->XDisplay(), mSurface->GetGLXPixmap());
       gl()->fDeleteTextures(1, &mTexture);
       mTexture = 0;
     }
   }
 }
 
 void
-X11TextureSourceOGL::BindTexture(GLenum aTextureUnit)
+X11TextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
 {
   gl()->fActiveTexture(aTextureUnit);
 
   if (!mTexture) {
     gl()->fGenTextures(1, &mTexture);
 
     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
 
     gl::sGLXLibrary.BindTexImage(mSurface->XDisplay(), mSurface->GetGLXPixmap());
   } else {
     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
     gl::sGLXLibrary.UpdateTexImage(mSurface->XDisplay(), mSurface->GetGLXPixmap());
   }
 
-  gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
+  ApplyFilterToBoundTexture(gl(), aFilter, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
 }
 
 IntSize
 X11TextureSourceOGL::GetSize() const
 {
   return ToIntSize(mSurface->GetSize());
 }
 
--- a/gfx/layers/opengl/X11TextureSourceOGL.h
+++ b/gfx/layers/opengl/X11TextureSourceOGL.h
@@ -21,17 +21,17 @@ class X11TextureSourceOGL
 {
 public:
   X11TextureSourceOGL(CompositorOGL* aCompositor, gfxXlibSurface* aSurface);
   ~X11TextureSourceOGL();
 
   virtual X11TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
 
   virtual bool IsValid() const MOZ_OVERRIDE { return !!gl(); } ;
-  virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
+  virtual void BindTexture(GLenum aTextureUnit, gfx::Filter aFilter) MOZ_OVERRIDE;
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
   virtual GLenum GetTextureTarget() const MOZ_OVERRIDE {
     return LOCAL_GL_TEXTURE_2D;
   }
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE {
      return LOCAL_GL_CLAMP_TO_EDGE;
   }