Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* vim: set ts=8 sts=4 et sw=4 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "DecomposeIntoNoRepeatTriangles.h"
8 #include "gfxMatrix.h"
10 namespace mozilla {
11 namespace gl {
13 void
14 RectTriangles::AppendRectToCoordArray(InfallibleTArray<coord>& array,
15 GLfloat x0, GLfloat y0,
16 GLfloat x1, GLfloat y1)
17 {
18 coord* v = array.AppendElements(6);
20 v[0].x = x0; v[0].y = y0;
21 v[1].x = x1; v[1].y = y0;
22 v[2].x = x0; v[2].y = y1;
23 v[3].x = x0; v[3].y = y1;
24 v[4].x = x1; v[4].y = y0;
25 v[5].x = x1; v[5].y = y1;
26 }
28 void
29 RectTriangles::addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
30 GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1,
31 bool flip_y /* = false */)
32 {
33 if (flip_y) {
34 std::swap(ty0, ty1);
35 }
36 AppendRectToCoordArray(mVertexCoords, x0, y0, x1, y1);
37 AppendRectToCoordArray(mTexCoords, tx0, ty0, tx1, ty1);
38 }
40 bool
41 RectTriangles::isSimpleQuad(gfx3DMatrix& aOutTextureTransform) const
42 {
43 if (mVertexCoords.Length() == 6 &&
44 mVertexCoords[0].x == 0.0f &&
45 mVertexCoords[0].y == 0.0f &&
46 mVertexCoords[5].x == 1.0f &&
47 mVertexCoords[5].y == 1.0f)
48 {
49 GLfloat tx0 = mTexCoords[0].x;
50 GLfloat ty0 = mTexCoords[0].y;
51 GLfloat tx1 = mTexCoords[5].x;
52 GLfloat ty1 = mTexCoords[5].y;
53 aOutTextureTransform = gfx3DMatrix::From2D(gfxMatrix(tx1 - tx0, 0, 0, ty1 - ty0, tx0, ty0));
54 return true;
55 }
56 return false;
57 }
59 static GLfloat
60 WrapTexCoord(GLfloat v)
61 {
62 // fmodf gives negative results for negative numbers;
63 // that is, fmodf(0.75, 1.0) == 0.75, but
64 // fmodf(-0.75, 1.0) == -0.75. For the negative case,
65 // the result we need is 0.25, so we add 1.0f.
66 if (v < 0.0f) {
67 return 1.0f + fmodf(v, 1.0f);
68 }
70 return fmodf(v, 1.0f);
71 }
73 void
74 DecomposeIntoNoRepeatTriangles(const nsIntRect& aTexCoordRect,
75 const nsIntSize& aTexSize,
76 RectTriangles& aRects,
77 bool aFlipY /* = false */)
78 {
79 // normalize this
80 nsIntRect tcr(aTexCoordRect);
81 while (tcr.x >= aTexSize.width)
82 tcr.x -= aTexSize.width;
83 while (tcr.y >= aTexSize.height)
84 tcr.y -= aTexSize.height;
86 // Compute top left and bottom right tex coordinates
87 GLfloat tl[2] =
88 { GLfloat(tcr.x) / GLfloat(aTexSize.width),
89 GLfloat(tcr.y) / GLfloat(aTexSize.height) };
90 GLfloat br[2] =
91 { GLfloat(tcr.XMost()) / GLfloat(aTexSize.width),
92 GLfloat(tcr.YMost()) / GLfloat(aTexSize.height) };
94 // then check if we wrap in either the x or y axis; if we do,
95 // then also use fmod to figure out the "true" non-wrapping
96 // texture coordinates.
98 bool xwrap = false, ywrap = false;
99 if (tcr.x < 0 || tcr.x > aTexSize.width ||
100 tcr.XMost() < 0 || tcr.XMost() > aTexSize.width)
101 {
102 xwrap = true;
103 tl[0] = WrapTexCoord(tl[0]);
104 br[0] = WrapTexCoord(br[0]);
105 }
107 if (tcr.y < 0 || tcr.y > aTexSize.height ||
108 tcr.YMost() < 0 || tcr.YMost() > aTexSize.height)
109 {
110 ywrap = true;
111 tl[1] = WrapTexCoord(tl[1]);
112 br[1] = WrapTexCoord(br[1]);
113 }
115 NS_ASSERTION(tl[0] >= 0.0f && tl[0] <= 1.0f &&
116 tl[1] >= 0.0f && tl[1] <= 1.0f &&
117 br[0] >= 0.0f && br[0] <= 1.0f &&
118 br[1] >= 0.0f && br[1] <= 1.0f,
119 "Somehow generated invalid texture coordinates");
121 // If xwrap is false, the texture will be sampled from tl[0]
122 // .. br[0]. If xwrap is true, then it will be split into tl[0]
123 // .. 1.0, and 0.0 .. br[0]. Same for the Y axis. The
124 // destination rectangle is also split appropriately, according
125 // to the calculated xmid/ymid values.
127 // There isn't a 1:1 mapping between tex coords and destination coords;
128 // when computing midpoints, we have to take that into account. We
129 // need to map the texture coords, which are (in the wrap case):
130 // |tl->1| and |0->br| to the |0->1| range of the vertex coords. So
131 // we have the length (1-tl)+(br) that needs to map into 0->1.
132 // These are only valid if there is wrap involved, they won't be used
133 // otherwise.
134 GLfloat xlen = (1.0f - tl[0]) + br[0];
135 GLfloat ylen = (1.0f - tl[1]) + br[1];
137 NS_ASSERTION(!xwrap || xlen > 0.0f, "xlen isn't > 0, what's going on?");
138 NS_ASSERTION(!ywrap || ylen > 0.0f, "ylen isn't > 0, what's going on?");
139 NS_ASSERTION(aTexCoordRect.width <= aTexSize.width &&
140 aTexCoordRect.height <= aTexSize.height, "tex coord rect would cause tiling!");
142 if (!xwrap && !ywrap) {
143 aRects.addRect(0.0f, 0.0f,
144 1.0f, 1.0f,
145 tl[0], tl[1],
146 br[0], br[1],
147 aFlipY);
148 } else if (!xwrap && ywrap) {
149 GLfloat ymid = (1.0f - tl[1]) / ylen;
150 aRects.addRect(0.0f, 0.0f,
151 1.0f, ymid,
152 tl[0], tl[1],
153 br[0], 1.0f,
154 aFlipY);
155 aRects.addRect(0.0f, ymid,
156 1.0f, 1.0f,
157 tl[0], 0.0f,
158 br[0], br[1],
159 aFlipY);
160 } else if (xwrap && !ywrap) {
161 GLfloat xmid = (1.0f - tl[0]) / xlen;
162 aRects.addRect(0.0f, 0.0f,
163 xmid, 1.0f,
164 tl[0], tl[1],
165 1.0f, br[1],
166 aFlipY);
167 aRects.addRect(xmid, 0.0f,
168 1.0f, 1.0f,
169 0.0f, tl[1],
170 br[0], br[1],
171 aFlipY);
172 } else {
173 GLfloat xmid = (1.0f - tl[0]) / xlen;
174 GLfloat ymid = (1.0f - tl[1]) / ylen;
175 aRects.addRect(0.0f, 0.0f,
176 xmid, ymid,
177 tl[0], tl[1],
178 1.0f, 1.0f,
179 aFlipY);
180 aRects.addRect(xmid, 0.0f,
181 1.0f, ymid,
182 0.0f, tl[1],
183 br[0], 1.0f,
184 aFlipY);
185 aRects.addRect(0.0f, ymid,
186 xmid, 1.0f,
187 tl[0], 0.0f,
188 1.0f, br[1],
189 aFlipY);
190 aRects.addRect(xmid, ymid,
191 1.0f, 1.0f,
192 0.0f, 0.0f,
193 br[0], br[1],
194 aFlipY);
195 }
196 }
198 }
199 }