Bug 971914 - Make TextureSourceOGL responsible for tracking filter state. r=nical

This commit is contained in:
Matt Woodrow 2014-03-13 13:37:17 +13:00
parent 0cf2747abe
commit af3af9a806
10 changed files with 74 additions and 57 deletions

View File

@ -705,7 +705,7 @@ SendTextureSource(GLContext* aGLContext,
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

View File

@ -70,7 +70,7 @@ 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);
}
@ -880,20 +880,6 @@ CompositorOGL::DrawLines(const std::vector<gfx::Point>& aLines, const gfx::Rect&
}
}
/**
* 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,
@ -1012,26 +998,23 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
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);
@ -1062,14 +1045,9 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
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);
@ -1094,7 +1072,7 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
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);
}
@ -1123,8 +1101,8 @@ CompositorOGL::DrawQuadInternal(const Rect& aRect,
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);

View File

@ -104,7 +104,7 @@ GrallocTextureSourceOGL::~GrallocTextureSourceOGL()
}
void
GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit)
GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
{
MOZ_ASSERT(gl());
if (!IsValid()) {
@ -118,7 +118,7 @@ GrallocTextureSourceOGL::BindTexture(GLenum aTextureUnit)
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(textureTarget, tex);
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
ApplyFilterToBoundTexture(gl(), aFilter, textureTarget);
}
void GrallocTextureSourceOGL::Lock()

View File

@ -30,7 +30,7 @@ public:
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;

View File

@ -84,7 +84,7 @@ MacIOSurfaceTextureSourceOGL::GetFormat() const
}
void
MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit)
MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
{
if (!gl()) {
NS_WARNING("Trying to bind a texture without a GLContext");
@ -95,7 +95,7 @@ MacIOSurfaceTextureSourceOGL::BindTexture(GLenum 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

View File

@ -29,7 +29,7 @@ public:
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(); }

View File

@ -246,6 +246,7 @@ TextureImageTextureSourceOGL::Update(gfx::DataSourceSurface* aSurface,
FlagsToGLFlags(mFlags),
SurfaceFormatToImageFormat(aSurface->GetFormat()));
}
ClearCachedFilter();
}
mTexImage->UpdateFromDataSource(aSurface, aDestRegion, aSrcOffset);
@ -293,11 +294,12 @@ nsIntRect TextureImageTextureSourceOGL::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,
@ -317,7 +319,7 @@ SharedTextureSourceOGL::SharedTextureSourceOGL(CompositorOGL* aCompositor,
{}
void
SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit)
SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
{
if (!gl()) {
NS_WARNING("Trying to bind a texture without a GLContext");
@ -331,6 +333,7 @@ SharedTextureSourceOGL::BindTexture(GLenum aTextureUnit)
NS_ERROR("Failed to bind shared texture handle");
return;
}
ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
}
void
@ -452,11 +455,12 @@ SharedTextureHostOGL::GetFormat() const
}
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
@ -538,6 +542,8 @@ StreamTextureSourceOGL::RetrieveTextureFromStream()
LOCAL_GL_TEXTURE_WRAP_T,
LOCAL_GL_CLAMP_TO_EDGE);
ClearCachedFilter();
return true;
}
@ -770,10 +776,11 @@ TiledDeprecatedTextureHostOGL::~TiledDeprecatedTextureHostOGL()
}
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
@ -835,10 +842,9 @@ TiledDeprecatedTextureHostOGL::Update(gfxReusableSurfaceWrapper* aReusableSurfac
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
@ -1052,7 +1058,7 @@ 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");
/*
@ -1075,6 +1081,7 @@ void GrallocDeprecatedTextureHostOGL::BindTexture(GLenum aTextureUnit)
gl()->fActiveTexture(aTextureUnit);
gl()->fBindTexture(mTextureTarget, tex);
ApplyFilterToBoundTexture(gl(), aFilter, mTextureTarget);
}
bool

View File

@ -77,6 +77,17 @@ 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.
*
@ -99,9 +110,13 @@ protected:
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;
@ -114,6 +129,23 @@ public:
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;
};
/**
@ -176,7 +208,7 @@ public:
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;
@ -249,7 +281,7 @@ public:
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;
@ -362,7 +394,7 @@ public:
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(); }
@ -495,7 +527,7 @@ public:
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);
}
@ -585,7 +617,7 @@ public:
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;
@ -667,7 +699,7 @@ public:
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
{

View File

@ -39,7 +39,7 @@ X11TextureSourceOGL::DeallocateDeviceData()
}
void
X11TextureSourceOGL::BindTexture(GLenum aTextureUnit)
X11TextureSourceOGL::BindTexture(GLenum aTextureUnit, gfx::Filter aFilter)
{
gl()->fActiveTexture(aTextureUnit);
@ -54,7 +54,7 @@ X11TextureSourceOGL::BindTexture(GLenum aTextureUnit)
gl::sGLXLibrary.UpdateTexImage(mSurface->XDisplay(), mSurface->GetGLXPixmap());
}
gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
ApplyFilterToBoundTexture(gl(), aFilter, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
}
IntSize

View File

@ -26,7 +26,7 @@ public:
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;