/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "SkGLState.h" #include "SkColorPriv.h" // here is our global instance SkGLState SkGLState::gState; // this is an illegal pmcolor, since its alpha (0) is less than its red #define UNKNOWN_PMCOLOR (SK_R32_MASK << SK_R32_SHIFT) #define UNKNOWN_GLENUM ((GLenum)-1) // MUST be in the same order as SkGLState::Caps enum static const GLenum gCapsTable[] = { GL_DITHER, GL_TEXTURE_2D, }; // MUST be in the same order as SkGLState::ClientState enum static const GLenum gClientStateTable[] = { GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY, }; static const GLenum gShadeModelTable[] = { GL_FLAT, GL_SMOOTH }; /////////////////////////////////////////////////////////////////////////////// SkGLState::SkGLState() : fCapsPtr(gCapsTable), fClientPtr(gClientStateTable), fShadePtr(gShadeModelTable) { this->init(); } void SkGLState::init() { fCapBits = 0; fClientStateBits = 0; fShadeModel = UNKNOWN_GLENUM; fScissorSize.set(-1, -1); fPMColor = UNKNOWN_PMCOLOR; fSrcBlend = fDstBlend = UNKNOWN_GLENUM; fPointSize = fLineWidth = -1; } void SkGLState::reset() { this->init(); size_t i; for (i = 0; i < SK_ARRAY_COUNT(gCapsTable); i++) { glDisable(fCapsPtr[i]); } for (i = 0; i < SK_ARRAY_COUNT(gClientStateTable); i++) { glDisableClientState(fClientPtr[i]); } } /////////////////////////////////////////////////////////////////////////////// void SkGLState::enable(Caps c) { unsigned mask = 1 << c; if ((fCapBits & mask) == 0) { fCapBits |= mask; glEnable(fCapsPtr[c]); } } void SkGLState::disable(Caps c) { unsigned mask = 1 << c; if (fCapBits & mask) { fCapBits &= ~mask; glDisable(fCapsPtr[c]); } } void SkGLState::enableClientState(ClientState c) { unsigned mask = 1 << c; if ((fClientStateBits & mask) == 0) { fClientStateBits |= mask; glEnableClientState(fClientPtr[c]); } } void SkGLState::disableClientState(ClientState c) { unsigned mask = 1 << c; if (fClientStateBits & mask) { fClientStateBits &= ~mask; glDisableClientState(fClientPtr[c]); } } void SkGLState::shadeModel(ShadeModel s) { if (fShadeModel != s) { fShadeModel = s; glShadeModel(fShadePtr[s]); } } void SkGLState::scissor(int x, int y, int w, int h) { SkASSERT(w >= 0 && h >= 0); if (!fScissorLoc.equals(x, y) || !fScissorSize.equals(w, h)) { fScissorLoc.set(x, y); fScissorSize.set(w, h); glScissor(x, y, w, h); } } void SkGLState::pointSize(float x) { if (fPointSize != x) { fPointSize = x; glPointSize(x); } } void SkGLState::lineWidth(float x) { if (fLineWidth != x) { fLineWidth = x; glLineWidth(x); } } void SkGLState::blendFunc(GLenum src, GLenum dst) { if (fSrcBlend != src || fDstBlend != dst) { fSrcBlend = src; fDstBlend = dst; glBlendFunc(src, dst); } } /////////////////////////////////////////////////////////////////////////////// #ifdef SK_GL_HAS_COLOR4UB static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) { glColor4ub(r, g, b, a); } #else static inline SkFixed byte2fixed(U8CPU value) { return ((value << 8) | value) + (value >> 7); } static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) { glColor4x(byte2fixed(r), byte2fixed(g), byte2fixed(b), byte2fixed(a)); } #endif void SkGLState::pmColor(SkPMColor c) { if (fPMColor != c) { fPMColor = c; gl_pmcolor(SkGetPackedR32(c), SkGetPackedG32(c), SkGetPackedB32(c), SkGetPackedA32(c)); } }