Bug 739648 - add mFlags field to TextureImage; introduce GetSrcTileRect flipping tile y-coords as needed; use it in DirectUpdate() to fix WebGL compositing bug - r=bgirard

This commit is contained in:
Benoit Jacob 2012-05-09 16:55:31 -04:00
parent ab1313c6c1
commit 875848ef77
7 changed files with 78 additions and 44 deletions

View File

@ -741,8 +741,9 @@ already_AddRefed<TextureImage>
GLContext::CreateTextureImage(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
GLenum aWrapMode,
bool aUseNearestFilter)
TextureImage::Flags aFlags)
{
bool useNearestFilter = aFlags & TextureImage::UseNearestFilter;
MakeCurrent();
GLuint texture;
@ -751,13 +752,13 @@ GLContext::CreateTextureImage(const nsIntSize& aSize,
fActiveTexture(LOCAL_GL_TEXTURE0);
fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
GLint texfilter = aUseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, aWrapMode);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, aWrapMode);
return CreateBasicTextureImage(texture, aSize, aWrapMode, aContentType, this);
return CreateBasicTextureImage(texture, aSize, aWrapMode, aContentType, this, aFlags);
}
void GLContext::ApplyFilterToBoundTexture(gfxPattern::GraphicsFilter aFilter)
@ -940,14 +941,13 @@ BasicTextureImage::Resize(const nsIntSize& aSize)
TiledTextureImage::TiledTextureImage(GLContext* aGL,
nsIntSize aSize,
TextureImage::ContentType aContentType,
bool aUseNearestFilter)
: TextureImage(aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, aUseNearestFilter)
TextureImage::Flags aFlags)
: TextureImage(aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, aFlags)
, mCurrentImage(0)
, mInUpdate(false)
, mRows(0)
, mColumns(0)
, mGL(aGL)
, mUseNearestFilter(aUseNearestFilter)
, mTextureState(Created)
, mIterationCallback(nsnull)
{
@ -977,7 +977,7 @@ TiledTextureImage::DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion,
int oldCurrentImage = mCurrentImage;
BeginTileIteration();
do {
nsIntRect tileRect = GetTileRect();
nsIntRect tileRect = GetSrcTileRect();
int xPos = tileRect.x;
int yPos = tileRect.y;
@ -1189,6 +1189,15 @@ nsIntRect TiledTextureImage::GetTileRect()
return rect;
}
nsIntRect TiledTextureImage::GetSrcTileRect()
{
nsIntRect rect = GetTileRect();
unsigned int srcY = mFlags & NeedsYFlip
? mSize.height - rect.height - rect.y
: rect.y;
return nsIntRect(rect.x, srcY, rect.width, rect.height);
}
void
TiledTextureImage::BindTexture(GLenum aTextureUnit)
{
@ -1269,7 +1278,7 @@ void TiledTextureImage::Resize(const nsIntSize& aSize)
// Create a new tile.
nsRefPtr<TextureImage> teximg =
mGL->TileGenFunc(size, mContentType, mUseNearestFilter);
mGL->TileGenFunc(size, mContentType, mFlags);
if (replace)
mImages.ReplaceElementAt(i, teximg.forget());
else

View File

@ -128,6 +128,12 @@ public:
Valid // Texture fully ready to use.
};
enum Flags {
NoFlags = 0x0,
UseNearestFilter = 0x1,
NeedsYFlip = 0x2
};
typedef gfxASurface::gfxContentType ContentType;
virtual ~TextureImage() {}
@ -319,18 +325,24 @@ protected:
*/
TextureImage(const nsIntSize& aSize,
GLenum aWrapMode, ContentType aContentType,
bool aIsRGB = false)
Flags aFlags = NoFlags)
: mSize(aSize)
, mWrapMode(aWrapMode)
, mContentType(aContentType)
, mFilter(gfxPattern::FILTER_GOOD)
, mFlags(aFlags)
{}
virtual nsIntRect GetSrcTileRect() {
return nsIntRect(nsIntPoint(0,0), mSize);
};
nsIntSize mSize;
GLenum mWrapMode;
ContentType mContentType;
ShaderProgramType mShaderType;
gfxPattern::GraphicsFilter mFilter;
Flags mFlags;
};
/**
@ -353,8 +365,9 @@ public:
const nsIntSize& aSize,
GLenum aWrapMode,
ContentType aContentType,
GLContext* aContext)
: TextureImage(aSize, aWrapMode, aContentType)
GLContext* aContext,
TextureImage::Flags aFlags = TextureImage::NoFlags)
: TextureImage(aSize, aWrapMode, aContentType, aFlags)
, mTexture(aTexture)
, mTextureState(Created)
, mGLContext(aContext)
@ -409,7 +422,7 @@ class TiledTextureImage
{
public:
TiledTextureImage(GLContext* aGL, nsIntSize aSize,
TextureImage::ContentType, bool aUseNearestFilter = false);
TextureImage::ContentType, TextureImage::Flags aFlags = TextureImage::NoFlags);
~TiledTextureImage();
void DumpDiv();
virtual gfxASurface* BeginUpdate(nsIntRegion& aRegion);
@ -429,7 +442,10 @@ public:
virtual bool InUpdate() const { return mInUpdate; };
virtual void BindTexture(GLenum);
virtual void ApplyFilter();
protected:
virtual nsIntRect GetSrcTileRect();
unsigned int mCurrentImage;
TileIterationCallback mIterationCallback;
void* mIterationCallbackData;
@ -439,7 +455,6 @@ protected:
unsigned int mTileSize;
unsigned int mRows, mColumns;
GLContext* mGL;
bool mUseNearestFilter;
// A temporary surface to faciliate cross-tile updates.
nsRefPtr<gfxASurface> mUpdateSurface;
// The region of update requested
@ -1382,7 +1397,8 @@ public:
* |aContentType|. The TextureImage's texture is configured to
* use |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by
* default, GL_LINEAR filtering. Specify
* |aUseNearestFilter=true| for GL_NEAREST filtering. Return
* |aFlags=UseNearestFilter| for GL_NEAREST filtering. Specify
* |aFlags=NeedsYFlip| if the image is flipped. Return
* NULL if creating the TextureImage fails.
*
* The returned TextureImage may only be used with this GLContext.
@ -1394,7 +1410,7 @@ public:
CreateTextureImage(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
GLenum aWrapMode,
bool aUseNearestFilter=false);
TextureImage::Flags aFlags = TextureImage::NoFlags);
/**
* In EGL we want to use Tiled Texture Images, which we return
@ -1406,7 +1422,7 @@ public:
virtual already_AddRefed<TextureImage>
TileGenFunc(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
bool aUseNearestFilter = false)
TextureImage::Flags aFlags = TextureImage::NoFlags)
{
return nsnull;
};
@ -1830,10 +1846,11 @@ protected:
const nsIntSize& aSize,
GLenum aWrapMode,
TextureImage::ContentType aContentType,
GLContext* aContext)
GLContext* aContext,
TextureImage::Flags aFlags = TextureImage::NoFlags)
{
nsRefPtr<BasicTextureImage> teximage(
new BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext));
new BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext, aFlags));
return teximage.forget();
}

View File

@ -210,7 +210,8 @@ public:
const nsIntSize& aSize,
GLenum aWrapMode,
TextureImage::ContentType aContentType,
GLContext* aContext);
GLContext* aContext,
TextureImage::Flags aFlags = TextureImage::NoFlags);
NSOpenGLContext *mContext;
NSOpenGLPixelBuffer *mPBuffer;
@ -315,7 +316,8 @@ class TextureImageCGL : public BasicTextureImage
const nsIntSize&,
GLenum,
TextureImage::ContentType,
GLContext*);
GLContext*,
TextureImage::Flags);
public:
~TextureImageCGL()
{
@ -401,8 +403,9 @@ private:
const nsIntSize& aSize,
GLenum aWrapMode,
ContentType aContentType,
GLContext* aContext)
: BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext)
GLContext* aContext,
TextureImage::Flags aFlags = TextureImage::NoFlags)
: BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext, aFlags)
, mPixelBuffer(0)
, mPixelBufferSize(0)
, mBoundPixelBuffer(false)
@ -418,10 +421,11 @@ GLContextCGL::CreateBasicTextureImage(GLuint aTexture,
const nsIntSize& aSize,
GLenum aWrapMode,
TextureImage::ContentType aContentType,
GLContext* aContext)
GLContext* aContext,
TextureImage::Flags aFlags)
{
nsRefPtr<TextureImageCGL> teximage
(new TextureImageCGL(aTexture, aSize, aWrapMode, aContentType, aContext));
(new TextureImageCGL(aTexture, aSize, aWrapMode, aContentType, aContext, aFlags));
return teximage.forget();
}

View File

@ -524,13 +524,13 @@ public:
CreateTextureImage(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
GLenum aWrapMode,
bool aUseNearestFilter=false);
TextureImage::Flags aFlags = TextureImage::NoFlags);
// a function to generate Tiles for Tiled Texture Image
virtual already_AddRefed<TextureImage>
TileGenFunc(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
bool aUseNearestFilter = false);
TextureImage::Flags aFlags = TextureImage::NoFlags);
// hold a reference to the given surface
// for the lifetime of this context.
void HoldSurface(gfxASurface *aSurf) {
@ -799,8 +799,9 @@ public:
const nsIntSize& aSize,
GLenum aWrapMode,
ContentType aContentType,
GLContext* aContext)
: TextureImage(aSize, aWrapMode, aContentType)
GLContext* aContext,
TextureImage::Flags aFlags = TextureImage::NoFlags)
: TextureImage(aSize, aWrapMode, aContentType, aFlags)
, mGLContext(aContext)
, mUpdateFormat(gfxASurface::ImageFormatUnknown)
, mSurface(nsnull)
@ -1293,16 +1294,16 @@ already_AddRefed<TextureImage>
GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
GLenum aWrapMode,
bool aUseNearestFilter)
TextureImage::Flags aFlags)
{
nsRefPtr<TextureImage> t = new gl::TiledTextureImage(this, aSize, aContentType, aUseNearestFilter);
nsRefPtr<TextureImage> t = new gl::TiledTextureImage(this, aSize, aContentType, aFlags);
return t.forget();
}
already_AddRefed<TextureImage>
GLContextEGL::TileGenFunc(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
bool aUseNearestFilter)
TextureImage::Flags aFlags)
{
MakeCurrent();
@ -1313,9 +1314,9 @@ GLContextEGL::TileGenFunc(const nsIntSize& aSize,
fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
nsRefPtr<TextureImageEGL> teximage =
new TextureImageEGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, this);
new TextureImageEGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType, this, aFlags);
GLint texfilter = aUseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
GLint texfilter = aFlags & TextureImage::UseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);

View File

@ -849,7 +849,7 @@ TRY_AGAIN_NO_SHARING:
CreateTextureImage(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
GLenum aWrapMode,
bool aUseNearestFilter = false);
TextureImage::Flags aFlags = TextureImage::NoFlags);
private:
friend class GLContextProviderGLX;
@ -886,7 +886,7 @@ class TextureImageGLX : public TextureImage
GLContextGLX::CreateTextureImage(const nsIntSize&,
ContentType,
GLenum,
bool);
TextureImage::Flags);
public:
virtual ~TextureImageGLX()
@ -950,8 +950,9 @@ private:
ContentType aContentType,
GLContext* aContext,
gfxASurface* aSurface,
GLXPixmap aPixmap)
: TextureImage(aSize, aWrapMode, aContentType)
GLXPixmap aPixmap,
TextureImage::Flags aFlags = TextureImage::NoFlags)
: TextureImage(aSize, aWrapMode, aContentType, aFlags)
, mGLContext(aContext)
, mUpdateSurface(aSurface)
, mPixmap(aPixmap)
@ -981,13 +982,13 @@ already_AddRefed<TextureImage>
GLContextGLX::CreateTextureImage(const nsIntSize& aSize,
TextureImage::ContentType aContentType,
GLenum aWrapMode,
bool aUseNearestFilter)
TextureImage::Flags aFlags)
{
if (!TextureImageSupportsGetBackingSurface()) {
return GLContext::CreateTextureImage(aSize,
aContentType,
aWrapMode,
aUseNearestFilter);
aFlags);
}
Display *display = DefaultXDisplay();
@ -1022,9 +1023,9 @@ GLContextGLX::CreateTextureImage(const nsIntSize& aSize,
fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
nsRefPtr<TextureImageGLX> teximage =
new TextureImageGLX(texture, aSize, aWrapMode, aContentType, this, surface, pixmap);
new TextureImageGLX(texture, aSize, aWrapMode, aContentType, this, surface, pixmap, aFlags);
GLint texfilter = aUseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
GLint texfilter = aFlags & TextureImage::UseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, aWrapMode);

View File

@ -339,10 +339,12 @@ ShadowCanvasLayerOGL::Init(const CanvasSurface& aNewFront, bool needYFlip)
{
nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
mNeedsYFlip = needYFlip;
mTexImage = gl()->CreateTextureImage(surf->GetSize(),
surf->GetContentType(),
LOCAL_GL_CLAMP_TO_EDGE);
mNeedsYFlip = needYFlip;
LOCAL_GL_CLAMP_TO_EDGE,
mNeedsYFlip ? TextureImage::NeedsYFlip : TextureImage::NoFlags);
}
void

View File

@ -1845,7 +1845,7 @@ nsChildView::DrawWindowOverlay(LayerManager* aManager, nsIntRect aRect)
mResizerImage = manager->gl()->CreateTextureImage(nsIntSize(15, 15),
gfxASurface::CONTENT_COLOR_ALPHA,
LOCAL_GL_CLAMP_TO_EDGE,
/* aUseNearestFilter = */ true);
TextureImage::UseNearestFilter);
// Creation of texture images can fail.
if (!mResizerImage)