diff --git a/gfx/layers/opengl/CompositorOGL.cpp b/gfx/layers/opengl/CompositorOGL.cpp index 361aa1bbf029..c9c2822538a0 100644 --- a/gfx/layers/opengl/CompositorOGL.cpp +++ b/gfx/layers/opengl/CompositorOGL.cpp @@ -412,6 +412,21 @@ CompositorOGL::Initialize() return true; } +/* + * Returns a size that is equal to, or larger than and closest to, + * aSize where both width and height are powers of two. + * If the OpenGL setup is capable of using non-POT textures, + * then it will just return aSize. + */ +static IntSize +CalculatePOTSize(const IntSize& aSize, GLContext* gl) +{ + if (CanUploadNonPowerOfTwo(gl)) + return aSize; + + return IntSize(NextPowerOfTwo(aSize.width), NextPowerOfTwo(aSize.height)); +} + // |aRect| is the rectangle we want to draw to. We will draw it with // up to 4 draw commands if necessary to avoid wrapping. // |aTexCoordRect| is the rectangle from the texture that we want to @@ -424,10 +439,26 @@ CompositorOGL::BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg, const Rect& aTexCoordRect, TextureSource *aTexture) { + Rect scaledTexCoordRect = aTexCoordRect; + + // If the OpenGL setup does not support non-power-of-two textures then the + // texture's width and height will have been increased to the next + // power-of-two (unless already a power of two). In that case we must scale + // the texture coordinates to account for that. + if (!CanUploadNonPowerOfTwo(mGLContext)) { + const IntSize& textureSize = aTexture->GetSize(); + const IntSize potSize = CalculatePOTSize(textureSize, mGLContext); + if (potSize != textureSize) { + const float xScale = (float)textureSize.width / (float)potSize.width; + const float yScale = (float)textureSize.height / (float)potSize.height; + scaledTexCoordRect.Scale(xScale, yScale); + } + } + Rect layerRects[4]; Rect textureRects[4]; size_t rects = DecomposeIntoNoRepeatRects(aRect, - aTexCoordRect, + scaledTexCoordRect, &layerRects, &textureRects); @@ -572,21 +603,6 @@ GetFrameBufferInternalFormat(GLContext* gl, return LOCAL_GL_RGBA; } -/* - * Returns a size that is larger than and closest to aSize where both - * width and height are powers of two. - * If the OpenGL setup is capable of using non-POT textures, then it - * will just return aSize. - */ -static IntSize -CalculatePOTSize(const IntSize& aSize, GLContext* gl) -{ - if (CanUploadNonPowerOfTwo(gl)) - return aSize; - - return IntSize(NextPowerOfTwo(aSize.width), NextPowerOfTwo(aSize.height)); -} - void CompositorOGL::ClearRect(const gfx::Rect& aRect) { diff --git a/gfx/thebes/gfxUtils.h b/gfx/thebes/gfxUtils.h index e538081dad65..a3c8bf2a58ed 100644 --- a/gfx/thebes/gfxUtils.h +++ b/gfx/thebes/gfxUtils.h @@ -336,8 +336,8 @@ IsPowerOfTwo(int aNumber) } /** - * Returns the first integer greater than |aNumber| which is a power of two - * Undefined for |aNumber| < 0 + * Returns the first integer greater than or equal to |aNumber| which is a + * power of two. Undefined for |aNumber| < 0. */ static inline int NextPowerOfTwo(int aNumber)