Bug 728625 - Add support for vertically flipping textured quads generated with RectTriangles and DecomposeIntoNoRepeatTriangles. r=bjacob,gw280

--HG--
extra : rebase_source : f42bd3c951651339d2ecb1286a6ac5c9e65ddd7d
This commit is contained in:
Joe Drew 2012-02-29 14:15:12 -08:00
Родитель df4746de60
Коммит 7c70bedfb2
5 изменённых файлов: 73 добавлений и 33 удалений

Просмотреть файл

@ -2455,7 +2455,8 @@ GLContext::TexSubImage2DWithoutUnpackSubimage(GLenum target, GLint level,
void
GLContext::RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1)
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
bool flip_y /* = false */)
{
vert_coord v;
v.x = x0; v.y = y0;
@ -2472,20 +2473,37 @@ GLContext::RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1
v.x = x1; v.y = y1;
vertexCoords.AppendElement(v);
tex_coord t;
t.u = tx0; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx0; t.v = ty1;
texCoords.AppendElement(t);
if (flip_y) {
tex_coord t;
t.u = tx0; t.v = ty1;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty1;
texCoords.AppendElement(t);
t.u = tx0; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx0; t.v = ty1;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty1;
texCoords.AppendElement(t);
t.u = tx0; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty1;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty0;
texCoords.AppendElement(t);
} else {
tex_coord t;
t.u = tx0; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx0; t.v = ty1;
texCoords.AppendElement(t);
t.u = tx0; t.v = ty1;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty0;
texCoords.AppendElement(t);
t.u = tx1; t.v = ty1;
texCoords.AppendElement(t);
}
}
static GLfloat
@ -2505,7 +2523,8 @@ WrapTexCoord(GLfloat v)
void
GLContext::DecomposeIntoNoRepeatTriangles(const nsIntRect& aTexCoordRect,
const nsIntSize& aTexSize,
RectTriangles& aRects)
RectTriangles& aRects,
bool aFlipY /* = false */)
{
// normalize this
nsIntRect tcr(aTexCoordRect);
@ -2574,46 +2593,55 @@ GLContext::DecomposeIntoNoRepeatTriangles(const nsIntRect& aTexCoordRect,
aRects.addRect(0.0f, 0.0f,
1.0f, 1.0f,
tl[0], tl[1],
br[0], br[1]);
br[0], br[1],
aFlipY);
} else if (!xwrap && ywrap) {
GLfloat ymid = (1.0f - tl[1]) / ylen;
aRects.addRect(0.0f, 0.0f,
1.0f, ymid,
tl[0], tl[1],
br[0], 1.0f);
br[0], 1.0f,
aFlipY);
aRects.addRect(0.0f, ymid,
1.0f, 1.0f,
tl[0], 0.0f,
br[0], br[1]);
br[0], br[1],
aFlipY);
} else if (xwrap && !ywrap) {
GLfloat xmid = (1.0f - tl[0]) / xlen;
aRects.addRect(0.0f, 0.0f,
xmid, 1.0f,
tl[0], tl[1],
1.0f, br[1]);
1.0f, br[1],
aFlipY);
aRects.addRect(xmid, 0.0f,
1.0f, 1.0f,
0.0f, tl[1],
br[0], br[1]);
br[0], br[1],
aFlipY);
} else {
GLfloat xmid = (1.0f - tl[0]) / xlen;
GLfloat ymid = (1.0f - tl[1]) / ylen;
aRects.addRect(0.0f, 0.0f,
xmid, ymid,
tl[0], tl[1],
1.0f, 1.0f);
1.0f, 1.0f,
aFlipY);
aRects.addRect(xmid, 0.0f,
1.0f, ymid,
0.0f, tl[1],
br[0], 1.0f);
br[0], 1.0f,
aFlipY);
aRects.addRect(0.0f, ymid,
xmid, 1.0f,
tl[0], 0.0f,
1.0f, br[1]);
1.0f, br[1],
aFlipY);
aRects.addRect(xmid, ymid,
1.0f, 1.0f,
0.0f, 0.0f,
br[0], br[1]);
br[0], br[1],
aFlipY);
}
}

Просмотреть файл

@ -1345,8 +1345,12 @@ public:
struct RectTriangles {
RectTriangles() { }
// Always pass texture coordinates upright. If you want to flip the
// texture coordinates emitted to the tex_coords array, set flip_y to
// true.
void addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1);
GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
bool flip_y = false);
/**
* these return a float pointer to the start of each array respectively.
@ -1377,7 +1381,8 @@ public:
* Decompose drawing the possibly-wrapped aTexCoordRect rectangle
* of a texture of aTexSize into one or more rectangles (represented
* as 2 triangles) and associated tex coordinates, such that
* we don't have to use the REPEAT wrap mode.
* we don't have to use the REPEAT wrap mode. If aFlipY is true, the
* texture coordinates will be specified vertically flipped.
*
* The resulting triangle vertex coordinates will be in the space of
* (0.0, 0.0) to (1.0, 1.0) -- transform the coordinates appropriately
@ -1388,7 +1393,8 @@ public:
*/
static void DecomposeIntoNoRepeatTriangles(const nsIntRect& aTexCoordRect,
const nsIntSize& aTexSize,
RectTriangles& aRects);
RectTriangles& aRects,
bool aFlipY = false);
/**
* Known GL extensions that can be queried by

Просмотреть файл

@ -437,7 +437,9 @@ ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
mOGLManager->BindAndDrawQuadWithTextureRect(program,
nsIntRect(0, 0, mTexImage->GetTileRect().width,
mTexImage->GetTileRect().height),
mTexImage->GetTileRect().Size());
mTexImage->GetTileRect().Size(),
mTexImage->GetWrapMode(),
mNeedsYFlip);
} while (mTexImage->NextTile());
}
}

Просмотреть файл

@ -674,7 +674,8 @@ void
LayerManagerOGL::BindAndDrawQuadWithTextureRect(LayerProgram *aProg,
const nsIntRect& aTexCoordRect,
const nsIntSize& aTexSize,
GLenum aWrapMode)
GLenum aWrapMode /* = LOCAL_GL_REPEAT */,
bool aFlipped /* = false */)
{
GLuint vertAttribIndex =
aProg->AttribLocation(LayerProgram::VertexAttrib);
@ -708,9 +709,11 @@ LayerManagerOGL::BindAndDrawQuadWithTextureRect(LayerProgram *aProg,
aTexCoordRect.x / GLfloat(realTexSize.width),
aTexCoordRect.y / GLfloat(realTexSize.height),
aTexCoordRect.XMost() / GLfloat(realTexSize.width),
aTexCoordRect.YMost() / GLfloat(realTexSize.height));
aTexCoordRect.YMost() / GLfloat(realTexSize.height),
aFlipped);
} else {
GLContext::DecomposeIntoNoRepeatTriangles(aTexCoordRect, realTexSize, rects);
GLContext::DecomposeIntoNoRepeatTriangles(aTexCoordRect, realTexSize,
rects, aFlipped);
}
mGLContext->fVertexAttribPointer(vertAttribIndex, 2,

Просмотреть файл

@ -366,8 +366,9 @@ public:
void BindAndDrawQuadWithTextureRect(LayerProgram *aProg,
const nsIntRect& aTexCoordRect,
const nsIntSize& aTexSize,
GLenum aWrapMode = LOCAL_GL_REPEAT);
GLenum aWrapMode = LOCAL_GL_REPEAT,
bool aFlipped = false);
#ifdef MOZ_LAYERS_HAVE_LOG
virtual const char* Name() const { return "OGL"; }