aboutsummaryrefslogtreecommitdiffstats
path: root/src/gl/SkGL.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gl/SkGL.cpp')
-rw-r--r--src/gl/SkGL.cpp526
1 files changed, 0 insertions, 526 deletions
diff --git a/src/gl/SkGL.cpp b/src/gl/SkGL.cpp
deleted file mode 100644
index 1fce98f..0000000
--- a/src/gl/SkGL.cpp
+++ /dev/null
@@ -1,526 +0,0 @@
-#include "SkGL.h"
-#include "SkColorPriv.h"
-#include "SkGeometry.h"
-#include "SkPaint.h"
-#include "SkPath.h"
-#include "SkTemplates.h"
-#include "SkXfermode.h"
-
-//#define TRACE_TEXTURE_CREATION
-
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_GL_HAS_COLOR4UB
-static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) {
- glColor4ub(r, g, b, a);
-}
-
-void SkGL::SetAlpha(U8CPU alpha) {
- glColor4ub(alpha, alpha, alpha, alpha);
-}
-#else
-static inline SkFixed byte2fixed(U8CPU value) {
- return (value + (value >> 7)) << 8;
-}
-
-static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) {
- glColor4x(byte2fixed(r), byte2fixed(g), byte2fixed(b), byte2fixed(a));
-}
-
-void SkGL::SetAlpha(U8CPU alpha) {
- SkFixed fa = byte2fixed(alpha);
- glColor4x(fa, fa, fa, fa);
-}
-#endif
-
-void SkGL::SetColor(SkColor c) {
- SkPMColor pm = SkPreMultiplyColor(c);
- gl_pmcolor(SkGetPackedR32(pm),
- SkGetPackedG32(pm),
- SkGetPackedB32(pm),
- SkGetPackedA32(pm));
-}
-
-static const GLenum gXfermodeCoeff2Blend[] = {
- GL_ZERO,
- GL_ONE,
- GL_SRC_COLOR,
- GL_ONE_MINUS_SRC_COLOR,
- GL_DST_COLOR,
- GL_ONE_MINUS_DST_COLOR,
- GL_SRC_ALPHA,
- GL_ONE_MINUS_SRC_ALPHA,
- GL_DST_ALPHA,
- GL_ONE_MINUS_DST_ALPHA,
-};
-
-void SkGL::SetPaint(const SkPaint& paint, bool isPremul, bool justAlpha) {
- if (justAlpha) {
- SkGL::SetAlpha(paint.getAlpha());
- } else {
- SkGL::SetColor(paint.getColor());
- }
-
- GLenum sm = GL_ONE;
- GLenum dm = GL_ONE_MINUS_SRC_ALPHA;
-
- SkXfermode* mode = paint.getXfermode();
- SkXfermode::Coeff sc, dc;
- if (mode && mode->asCoeff(&sc, &dc)) {
- sm = gXfermodeCoeff2Blend[sc];
- dm = gXfermodeCoeff2Blend[dc];
- }
-
- // hack for text, which is not-premul (afaik)
- if (!isPremul) {
- if (GL_ONE == sm) {
- sm = GL_SRC_ALPHA;
- }
- }
-
- glEnable(GL_BLEND);
- glBlendFunc(sm, dm);
-
- if (paint.isDither()) {
- glEnable(GL_DITHER);
- } else {
- glDisable(GL_DITHER);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkGL::DumpError(const char caller[]) {
- GLenum err = glGetError();
- if (err) {
- SkDebugf("---- glGetError(%s) %d\n", caller, err);
- }
-}
-
-void SkGL::SetRGBA(uint8_t rgba[], const SkColor src[], int count) {
- for (int i = 0; i < count; i++) {
- SkPMColor c = SkPreMultiplyColor(*src++);
- *rgba++ = SkGetPackedR32(c);
- *rgba++ = SkGetPackedG32(c);
- *rgba++ = SkGetPackedB32(c);
- *rgba++ = SkGetPackedA32(c);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkGL::Scissor(const SkIRect& r, int viewportHeight) {
- glScissor(r.fLeft, viewportHeight - r.fBottom, r.width(), r.height());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkGL::Ortho(float left, float right, float bottom, float top,
- float near, float far) {
-
- float mat[16];
-
- sk_bzero(mat, sizeof(mat));
-
- mat[0] = 2 / (right - left);
- mat[5] = 2 / (top - bottom);
- mat[10] = 2 / (near - far);
- mat[15] = 1;
-
- mat[12] = (right + left) / (left - right);
- mat[13] = (top + bottom) / (bottom - top);
- mat[14] = (far + near) / (near - far);
-
- glMultMatrixf(mat);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-static bool canBeTexture(const SkBitmap& bm, GLenum* format, GLenum* type) {
- switch (bm.config()) {
- case SkBitmap::kARGB_8888_Config:
- *format = GL_RGBA;
- *type = GL_UNSIGNED_BYTE;
- break;
- case SkBitmap::kRGB_565_Config:
- *format = GL_RGB;
- *type = GL_UNSIGNED_SHORT_5_6_5;
- break;
- case SkBitmap::kARGB_4444_Config:
- *format = GL_RGBA;
- *type = GL_UNSIGNED_SHORT_4_4_4_4;
- break;
- case SkBitmap::kIndex8_Config:
-#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
- *format = GL_PALETTE8_RGBA8_OES;
- *type = GL_UNSIGNED_BYTE; // unused I think
-#else
- // we promote index to argb32
- *format = GL_RGBA;
- *type = GL_UNSIGNED_BYTE;
-#endif
- break;
- case SkBitmap::kA8_Config:
- *format = GL_ALPHA;
- *type = GL_UNSIGNED_BYTE;
- break;
- default:
- return false;
- }
- return true;
-}
-
-#define SK_GL_SIZE_OF_PALETTE (256 * sizeof(SkPMColor))
-
-size_t SkGL::ComputeTextureMemorySize(const SkBitmap& bitmap) {
- int shift = 0;
- size_t adder = 0;
- switch (bitmap.config()) {
- case SkBitmap::kARGB_8888_Config:
- case SkBitmap::kRGB_565_Config:
- case SkBitmap::kARGB_4444_Config:
- case SkBitmap::kA8_Config:
- // we're good as is
- break;
- case SkBitmap::kIndex8_Config:
-#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
- // account for the colortable
- adder = SK_GL_SIZE_OF_PALETTE;
-#else
- // we promote index to argb32
- shift = 2;
-#endif
- break;
- default:
- return 0;
- }
- return (bitmap.getSize() << shift) + adder;
-}
-
-#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
-/* Fill out buffer with the compressed format GL expects from a colortable
- based bitmap. [palette (colortable) + indices].
-
- At the moment I always take the 8bit version, since that's what my data
- is. I could detect that the colortable.count is <= 16, and then repack the
- indices as nibbles to save RAM, but it would take more time (i.e. a lot
- slower than memcpy), so I'm skipping that for now.
-
- GL wants a full 256 palette entry, even though my ctable is only as big
- as the colortable.count says it is. I presume it is OK to leave any
- trailing entries uninitialized, since none of my indices should exceed
- ctable->count().
-*/
-static void build_compressed_data(void* buffer, const SkBitmap& bitmap) {
- SkASSERT(SkBitmap::kIndex8_Config == bitmap.config());
-
- SkColorTable* ctable = bitmap.getColorTable();
- uint8_t* dst = (uint8_t*)buffer;
-
- memcpy(dst, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
- ctable->unlockColors(false);
-
- // always skip a full 256 number of entries, even if we memcpy'd fewer
- dst += SK_GL_SIZE_OF_PALETTE;
- memcpy(dst, bitmap.getPixels(), bitmap.getSize());
-}
-#endif
-
-/* Return true if the bitmap cannot be supported in its current config as a
- texture, and it needs to be promoted to ARGB32.
- */
-static bool needToPromoteTo32bit(const SkBitmap& bitmap) {
- if (bitmap.config() == SkBitmap::kIndex8_Config) {
-#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
- const int w = bitmap.width();
- const int h = bitmap.height();
- if (SkNextPow2(w) == w && SkNextPow2(h) == h) {
- // we can handle Indx8 if we're a POW2
- return false;
- }
-#endif
- return true; // must promote to ARGB32
- }
- return false;
-}
-
-GLuint SkGL::BindNewTexture(const SkBitmap& origBitmap, SkPoint* max) {
- SkBitmap tmpBitmap;
- const SkBitmap* bitmap = &origBitmap;
-
- if (needToPromoteTo32bit(origBitmap)) {
- origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
- // now bitmap points to our temp, which has been promoted to 32bits
- bitmap = &tmpBitmap;
- }
-
- GLenum format, type;
- if (!canBeTexture(*bitmap, &format, &type)) {
- return 0;
- }
-
- SkAutoLockPixels alp(*bitmap);
- if (!bitmap->readyToDraw()) {
- return 0;
- }
-
- GLuint textureName;
- glGenTextures(1, &textureName);
-
- glBindTexture(GL_TEXTURE_2D, textureName);
-
- // express rowbytes as a number of pixels for ow
- int ow = bitmap->rowBytesAsPixels();
- int oh = bitmap->height();
- int nw = SkNextPow2(ow);
- int nh = SkNextPow2(oh);
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());
-
- // check if we need to scale to create power-of-2 dimensions
-#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
- if (SkBitmap::kIndex8_Config == bitmap->config()) {
- size_t imagesize = bitmap->getSize() + SK_GL_SIZE_OF_PALETTE;
- SkAutoMalloc storage(imagesize);
-
- build_compressed_data(storage.get(), *bitmap);
- // we only support POW2 here (GLES 1.0 restriction)
- SkASSERT(ow == nw);
- SkASSERT(oh == nh);
- glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0,
- imagesize, storage.get());
- } else // fall through to non-compressed logic
-#endif
- {
- if (ow != nw || oh != nh) {
- glTexImage2D(GL_TEXTURE_2D, 0, format, nw, nh, 0,
- format, type, NULL);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ow, oh,
- format, type, bitmap->getPixels());
- } else {
- // easy case, the bitmap is already pow2
- glTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0,
- format, type, bitmap->getPixels());
- }
- }
-
-#ifdef TRACE_TEXTURE_CREATION
- SkDebugf("--- new texture [%d] size=(%d %d) bpp=%d\n", textureName, ow, oh,
- bitmap->bytesPerPixel());
-#endif
-
- if (max) {
- max->fX = SkFixedToScalar(bitmap->width() << (16 - SkNextLog2(nw)));
- max->fY = SkFixedToScalar(oh << (16 - SkNextLog2(nh)));
- }
- return textureName;
-}
-
-static const GLenum gTileMode2GLWrap[] = {
- GL_CLAMP_TO_EDGE,
- GL_REPEAT,
-#if GL_VERSION_ES_CM_1_0
- GL_REPEAT // GLES doesn't support MIRROR
-#else
- GL_MIRRORED_REPEAT
-#endif
-};
-
-void SkGL::SetTexParams(bool doFilter,
- SkShader::TileMode tx, SkShader::TileMode ty) {
- SkASSERT((unsigned)tx < SK_ARRAY_COUNT(gTileMode2GLWrap));
- SkASSERT((unsigned)ty < SK_ARRAY_COUNT(gTileMode2GLWrap));
-
- GLenum filter = doFilter ? GL_LINEAR : GL_NEAREST;
-
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, gTileMode2GLWrap[tx]);
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, gTileMode2GLWrap[ty]);
-}
-
-void SkGL::SetTexParamsClamp(bool doFilter) {
- GLenum filter = doFilter ? GL_LINEAR : GL_NEAREST;
-
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-void SkGL::DrawVertices(int count, GLenum mode,
- const SkGLVertex* SK_RESTRICT vertex,
- const SkGLVertex* SK_RESTRICT texCoords,
- const uint8_t* SK_RESTRICT colorArray,
- const uint16_t* SK_RESTRICT indexArray,
- SkGLClipIter* iter) {
- SkASSERT(NULL != vertex);
-
- if (NULL != texCoords) {
- glEnable(GL_TEXTURE_2D);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, SK_GLType, 0, texCoords);
- } else {
- glDisable(GL_TEXTURE_2D);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- }
-
- if (NULL != colorArray) {
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(4, GL_UNSIGNED_BYTE, 0, colorArray);
- glShadeModel(GL_SMOOTH);
- } else {
- glDisableClientState(GL_COLOR_ARRAY);
- glShadeModel(GL_FLAT);
- }
-
- glVertexPointer(2, SK_GLType, 0, vertex);
-
- if (NULL != indexArray) {
- if (iter) {
- while (!iter->done()) {
- iter->scissor();
- glDrawElements(mode, count, GL_UNSIGNED_SHORT, indexArray);
- iter->next();
- }
- } else {
- glDrawElements(mode, count, GL_UNSIGNED_SHORT, indexArray);
- }
- } else {
- if (iter) {
- while (!iter->done()) {
- iter->scissor();
- glDrawArrays(mode, 0, count);
- iter->next();
- }
- } else {
- glDrawArrays(mode, 0, count);
- }
- }
-}
-
-void SkGL::PrepareForFillPath(SkPaint* paint) {
- if (paint->getStrokeWidth() <= 0) {
- paint->setStrokeWidth(SK_Scalar1);
- }
-}
-
-void SkGL::FillPath(const SkPath& path, const SkPaint& paint, bool useTex,
- SkGLClipIter* iter) {
- SkPaint p(paint);
- SkPath fillPath;
-
- SkGL::PrepareForFillPath(&p);
- p.getFillPath(path, &fillPath);
- SkGL::DrawPath(fillPath, useTex, iter);
-}
-
-// should return max of all contours, rather than the sum (to save temp RAM)
-static int worst_case_edge_count(const SkPath& path) {
- int edgeCount = 0;
-
- SkPath::Iter iter(path, true);
- SkPath::Verb verb;
-
- while ((verb = iter.next(NULL)) != SkPath::kDone_Verb) {
- switch (verb) {
- case SkPath::kLine_Verb:
- edgeCount += 1;
- break;
- case SkPath::kQuad_Verb:
- edgeCount += 8;
- break;
- case SkPath::kCubic_Verb:
- edgeCount += 16;
- break;
- default:
- break;
- }
- }
- return edgeCount;
-}
-
-void SkGL::DrawPath(const SkPath& path, bool useTex, SkGLClipIter* clipIter) {
- const SkRect& bounds = path.getBounds();
- if (bounds.isEmpty()) {
- return;
- }
-
- int maxPts = worst_case_edge_count(path);
- // add 1 for center of fan, and 1 for closing edge
- SkAutoSTMalloc<32, SkGLVertex> storage(maxPts + 2);
- SkGLVertex* base = storage.get();
- SkGLVertex* vert = base;
- SkGLVertex* texs = useTex ? base : NULL;
-
- SkPath::Iter pathIter(path, true);
- SkPoint pts[4];
-
- bool needEnd = false;
-
- for (;;) {
- switch (pathIter.next(pts)) {
- case SkPath::kMove_Verb:
- if (needEnd) {
- SkGL::DrawVertices(vert - base, GL_TRIANGLE_FAN,
- base, texs, NULL, NULL, clipIter);
- clipIter->safeRewind();
- vert = base;
- }
- needEnd = true;
- // center of the FAN
- vert->setScalars(bounds.centerX(), bounds.centerY());
- vert++;
- // add first edge point
- vert->setPoint(pts[0]);
- vert++;
- break;
- case SkPath::kLine_Verb:
- vert->setPoint(pts[1]);
- vert++;
- break;
- case SkPath::kQuad_Verb: {
- const int n = 8;
- const SkScalar dt = SK_Scalar1 / n;
- SkScalar t = dt;
- for (int i = 1; i < n; i++) {
- SkPoint loc;
- SkEvalQuadAt(pts, t, &loc, NULL);
- t += dt;
- vert->setPoint(loc);
- vert++;
- }
- vert->setPoint(pts[2]);
- vert++;
- break;
- }
- case SkPath::kCubic_Verb: {
- const int n = 16;
- const SkScalar dt = SK_Scalar1 / n;
- SkScalar t = dt;
- for (int i = 1; i < n; i++) {
- SkPoint loc;
- SkEvalCubicAt(pts, t, &loc, NULL, NULL);
- t += dt;
- vert->setPoint(loc);
- vert++;
- }
- vert->setPoint(pts[3]);
- vert++;
- break;
- }
- case SkPath::kClose_Verb:
- break;
- case SkPath::kDone_Verb:
- goto FINISHED;
- }
- }
-FINISHED:
- if (needEnd) {
- SkGL::DrawVertices(vert - base, GL_TRIANGLE_FAN, base, texs,
- NULL, NULL, clipIter);
- }
-}
-