1 #ifndef SkGL_DEFINED 2 #define SkGL_DEFINED 3 4 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_SDL) 5 #include <OpenGL/gl.h> 6 #include <OpenGL/glext.h> 7 #include <AGL/agl.h> 8 // use FBOs for devices 9 #define SK_GL_DEVICE_FBO 10 #elif defined(ANDROID) 11 #include <GLES/gl.h> 12 #include <EGL/egl.h> 13 #include <GLES/glext.h> 14 #endif 15 16 #include "SkColor.h" 17 #include "SkMatrix.h" 18 #include "SkShader.h" 19 20 class SkPaint; 21 class SkPath; 22 23 class SkGLClipIter; 24 25 //#define TRACE_TEXTURE_CREATE 26 27 static void SkGL_unimpl(const char str[]) { 28 SkDebugf("SkGL unimplemented: %s\n", str); 29 } 30 /////////////////////////////////////////////////////////////////////////////// 31 32 #if GL_OES_compressed_paletted_texture 33 #define SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D 34 #endif 35 36 #if GL_OES_fixed_point && defined(SK_SCALAR_IS_FIXED) 37 #define SK_GLType GL_FIXED 38 #else 39 #define SK_GLType GL_FLOAT 40 #endif 41 42 #if SK_GLType == GL_FIXED 43 typedef SkFixed SkGLScalar; 44 45 #define SkIntToGL(n) SkIntToFixed(n) 46 #define SkScalarToGL(x) SkScalarToFixed(x) 47 #define SK_GLScalar1 SK_Fixed1 48 #define SkGLScalarMul(a, b) SkFixedMul(a, b) 49 #define MAKE_GL(name) name ## x 50 51 #ifdef SK_SCALAR_IS_FIXED 52 #define GLSCALAR_IS_SCALAR 1 53 #define SkPerspToGL(x) SkFractToFixed(x) 54 #else 55 #define GLSCALAR_IS_SCALAR 0 56 #define SkPerspToGL(x) SkFractToFloat(x) 57 #endif 58 #else 59 typedef float SkGLScalar; 60 61 #define SkIntToGL(n) (n) 62 #define SkScalarToGL(x) SkScalarToFloat(x) 63 #define SK_GLScalar1 (1.f) 64 #define SkGLScalarMul(a, b) ((a) * (b)) 65 #define MAKE_GL(name) name ## f 66 67 #ifdef SK_SCALAR_IS_FLOAT 68 #define GLSCALAR_IS_SCALAR 1 69 #define SkPerspToGL(x) (x) 70 #else 71 #define GLSCALAR_IS_SCALAR 0 72 #define SkPerspToGL(x) SkFractToFloat(x) 73 #endif 74 #endif 75 76 #if GL_OES_fixed_point 77 typedef SkFixed SkGLTextScalar; 78 #define SK_TextGLType GL_FIXED 79 80 #define SkIntToTextGL(n) SkIntToFixed(n) 81 #define SkFixedToTextGL(x) (x) 82 83 #define SK_glTexParameteri(target, pname, param) \ 84 glTexParameterx(target, pname, param) 85 #else 86 typedef float SkGLTextScalar; 87 #define SK_TextGLType SK_GLType 88 #define SK_GL_HAS_COLOR4UB 89 90 #define SkIntToTextGL(n) SkIntToGL(n) 91 #define SkFixedToTextGL(x) SkFixedToFloat(x) 92 93 94 #define SK_glTexParameteri(target, pname, param) \ 95 glTexParameteri(target, pname, param) 96 #endif 97 98 /////////////////////////////////////////////////////////////////////////////// 99 100 // text has its own vertex class, since it may want to be in fixed point (given) 101 // that it starts with all integers) even when the default vertices are floats 102 struct SkGLTextVertex { 103 SkGLTextScalar fX; 104 SkGLTextScalar fY; 105 106 void setI(int x, int y) { 107 fX = SkIntToTextGL(x); 108 fY = SkIntToTextGL(y); 109 } 110 111 void setX(SkFixed x, SkFixed y) { 112 fX = SkFixedToTextGL(x); 113 fY = SkFixedToTextGL(y); 114 } 115 116 // counter-clockwise fan 117 void setIRectFan(int l, int t, int r, int b) { 118 SkGLTextVertex* SK_RESTRICT v = this; 119 v[0].setI(l, t); 120 v[1].setI(l, b); 121 v[2].setI(r, b); 122 v[3].setI(r, t); 123 } 124 125 // counter-clockwise fan 126 void setXRectFan(SkFixed l, SkFixed t, SkFixed r, SkFixed b) { 127 SkGLTextVertex* SK_RESTRICT v = this; 128 v[0].setX(l, t); 129 v[1].setX(l, b); 130 v[2].setX(r, b); 131 v[3].setX(r, t); 132 } 133 }; 134 135 struct SkGLVertex { 136 SkGLScalar fX; 137 SkGLScalar fY; 138 139 void setGL(SkGLScalar x, SkGLScalar y) { 140 fX = x; 141 fY = y; 142 } 143 144 void setScalars(SkScalar x, SkScalar y) { 145 fX = SkScalarToGL(x); 146 fY = SkScalarToGL(y); 147 } 148 149 void setPoint(const SkPoint& pt) { 150 fX = SkScalarToGL(pt.fX); 151 fY = SkScalarToGL(pt.fY); 152 } 153 154 void setPoints(const SkPoint* SK_RESTRICT pts, int count) { 155 const SkScalar* SK_RESTRICT src = (const SkScalar*)pts; 156 SkGLScalar* SK_RESTRICT dst = (SkGLScalar*)this; 157 for (int i = 0; i < count; i++) { 158 *dst++ = SkScalarToGL(*src++); 159 *dst++ = SkScalarToGL(*src++); 160 } 161 } 162 163 // counter-clockwise fan 164 void setRectFan(SkScalar l, SkScalar t, SkScalar r, SkScalar b) { 165 SkGLVertex* v = this; 166 v[0].setScalars(l, t); 167 v[1].setScalars(l, b); 168 v[2].setScalars(r, b); 169 v[3].setScalars(r, t); 170 } 171 172 // counter-clockwise fan 173 void setIRectFan(int l, int t, int r, int b) { 174 SkGLVertex* v = this; 175 v[0].setGL(SkIntToGL(l), SkIntToGL(t)); 176 v[1].setGL(SkIntToGL(l), SkIntToGL(b)); 177 v[2].setGL(SkIntToGL(r), SkIntToGL(b)); 178 v[3].setGL(SkIntToGL(r), SkIntToGL(t)); 179 } 180 181 // counter-clockwise fan 182 void setRectFan(const SkRect& r) { 183 this->setRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom); 184 } 185 186 // counter-clockwise fan 187 void setIRectFan(const SkIRect& r) { 188 this->setIRectFan(r.fLeft, r.fTop, r.fRight, r.fBottom); 189 } 190 }; 191 192 struct SkGLMatrix { 193 SkGLScalar fMat[16]; 194 195 void reset() { 196 sk_bzero(fMat, sizeof(fMat)); 197 fMat[0] = fMat[5] = fMat[10] = fMat[15] = SK_GLScalar1; 198 } 199 200 void set(const SkMatrix& m) { 201 sk_bzero(fMat, sizeof(fMat)); 202 fMat[0] = SkScalarToGL(m[SkMatrix::kMScaleX]); 203 fMat[4] = SkScalarToGL(m[SkMatrix::kMSkewX]); 204 fMat[12] = SkScalarToGL(m[SkMatrix::kMTransX]); 205 206 fMat[1] = SkScalarToGL(m[SkMatrix::kMSkewY]); 207 fMat[5] = SkScalarToGL(m[SkMatrix::kMScaleY]); 208 fMat[13] = SkScalarToGL(m[SkMatrix::kMTransY]); 209 210 fMat[3] = SkPerspToGL(m[SkMatrix::kMPersp0]); 211 fMat[7] = SkPerspToGL(m[SkMatrix::kMPersp1]); 212 fMat[15] = SkPerspToGL(m[SkMatrix::kMPersp2]); 213 214 fMat[10] = SK_GLScalar1; // z-scale 215 } 216 }; 217 218 class SkGL { 219 public: 220 static void SetColor(SkColor c); 221 static void SetAlpha(U8CPU alpha); 222 static void SetPaint(const SkPaint&, bool isPremul = true, 223 bool justAlpha = false); 224 static void SetPaintAlpha(const SkPaint& paint, bool isPremul = true) { 225 SetPaint(paint, isPremul, true); 226 } 227 228 static void SetRGBA(uint8_t rgba[], const SkColor src[], int count); 229 static void DumpError(const char caller[]); 230 231 static void Ortho(float left, float right, float bottom, float top, 232 float near, float far); 233 234 static inline void Translate(SkScalar dx, SkScalar dy) { 235 MAKE_GL(glTranslate)(SkScalarToGL(dx), SkScalarToGL(dy), 0); 236 } 237 238 static inline void Scale(SkScalar sx, SkScalar sy) { 239 MAKE_GL(glScale)(SkScalarToGL(sx), SkScalarToGL(sy), SK_GLScalar1); 240 } 241 242 static inline void Rotate(SkScalar angle) { 243 MAKE_GL(glRotate)(SkScalarToGL(angle), 0, 0, SK_GLScalar1); 244 } 245 246 static inline void MultMatrix(const SkMatrix& m) { 247 SkGLMatrix glm; 248 glm.set(m); 249 MAKE_GL(glMultMatrix)(glm.fMat); 250 } 251 252 static inline void LoadMatrix(const SkMatrix& m) { 253 SkGLMatrix glm; 254 glm.set(m); 255 MAKE_GL(glLoadMatrix)(glm.fMat); 256 } 257 258 static void Scissor(const SkIRect&, int viewportHeight); 259 260 // return the byte size for the associated texture memory. This doesn't 261 // always == bitmap.getSize(), since on a given port we may have to change 262 // the format when the bitmap's pixels are copied over to GL 263 static size_t ComputeTextureMemorySize(const SkBitmap&); 264 // return 0 on failure 265 static GLuint BindNewTexture(const SkBitmap&, SkPoint* dimension); 266 267 static void SetTexParams(bool filter, 268 SkShader::TileMode tx, SkShader::TileMode ty); 269 static void SetTexParamsClamp(bool filter); 270 271 static void DrawVertices(int count, GLenum mode, 272 const SkGLVertex* SK_RESTRICT vertex, 273 const SkGLVertex* SK_RESTRICT texCoords, 274 const uint8_t* SK_RESTRICT colorArray, 275 const uint16_t* SK_RESTRICT indexArray, 276 SkGLClipIter*); 277 278 static void PrepareForFillPath(SkPaint* paint); 279 static void FillPath(const SkPath& path, const SkPaint& paint, bool useTex, 280 SkGLClipIter*); 281 static void DrawPath(const SkPath& path, bool useTex, SkGLClipIter*); 282 }; 283 284 #include "SkRegion.h" 285 286 class SkGLClipIter : public SkRegion::Iterator { 287 public: 288 SkGLClipIter(int viewportHeight) : fViewportHeight(viewportHeight) {} 289 290 // call rewind only if this is non-null 291 void safeRewind() { 292 if (this) { 293 this->rewind(); 294 } 295 } 296 297 void scissor() { 298 SkASSERT(!this->done()); 299 SkGL::Scissor(this->rect(), fViewportHeight); 300 } 301 302 private: 303 const int fViewportHeight; 304 }; 305 306 #endif 307 308