blob: 72170697e6f316caeddf01e4c3b6063f84da02ac [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.comb34086a2009-06-12 19:49:30 +00008#include "SkGLState.h"
9#include "SkColorPriv.h"
10
11// here is our global instance
12SkGLState SkGLState::gState;
13
14// this is an illegal pmcolor, since its alpha (0) is less than its red
15#define UNKNOWN_PMCOLOR (SK_R32_MASK << SK_R32_SHIFT)
16
17#define UNKNOWN_GLENUM ((GLenum)-1)
18
19// MUST be in the same order as SkGLState::Caps enum
20static const GLenum gCapsTable[] = {
21 GL_DITHER,
22 GL_TEXTURE_2D,
23};
24
25// MUST be in the same order as SkGLState::ClientState enum
26static const GLenum gClientStateTable[] = {
27 GL_TEXTURE_COORD_ARRAY,
28 GL_COLOR_ARRAY,
29};
30
31static const GLenum gShadeModelTable[] = {
32 GL_FLAT,
33 GL_SMOOTH
34};
35
36///////////////////////////////////////////////////////////////////////////////
37
38SkGLState::SkGLState() :
39 fCapsPtr(gCapsTable),
40 fClientPtr(gClientStateTable),
41 fShadePtr(gShadeModelTable) {
42 this->init();
43}
44
45void SkGLState::init() {
46 fCapBits = 0;
47 fClientStateBits = 0;
48 fShadeModel = UNKNOWN_GLENUM;
49 fScissorSize.set(-1, -1);
50 fPMColor = UNKNOWN_PMCOLOR;
51 fSrcBlend = fDstBlend = UNKNOWN_GLENUM;
52 fPointSize = fLineWidth = -1;
53}
54
55void SkGLState::reset() {
56 this->init();
57
58 size_t i;
59 for (i = 0; i < SK_ARRAY_COUNT(gCapsTable); i++) {
60 glDisable(fCapsPtr[i]);
61 }
62 for (i = 0; i < SK_ARRAY_COUNT(gClientStateTable); i++) {
63 glDisableClientState(fClientPtr[i]);
64 }
65}
66
67///////////////////////////////////////////////////////////////////////////////
68
69void SkGLState::enable(Caps c) {
70 unsigned mask = 1 << c;
71 if ((fCapBits & mask) == 0) {
72 fCapBits |= mask;
73 glEnable(fCapsPtr[c]);
74 }
75}
76
77void SkGLState::disable(Caps c) {
78 unsigned mask = 1 << c;
79 if (fCapBits & mask) {
80 fCapBits &= ~mask;
81 glDisable(fCapsPtr[c]);
82 }
83}
84
85void SkGLState::enableClientState(ClientState c) {
86 unsigned mask = 1 << c;
87 if ((fClientStateBits & mask) == 0) {
88 fClientStateBits |= mask;
89 glEnableClientState(fClientPtr[c]);
90 }
91}
92
93void SkGLState::disableClientState(ClientState c) {
94 unsigned mask = 1 << c;
95 if (fClientStateBits & mask) {
96 fClientStateBits &= ~mask;
97 glDisableClientState(fClientPtr[c]);
98 }
99}
100
101void SkGLState::shadeModel(ShadeModel s) {
102 if (fShadeModel != s) {
103 fShadeModel = s;
104 glShadeModel(fShadePtr[s]);
105 }
106}
107
108void SkGLState::scissor(int x, int y, int w, int h) {
109 SkASSERT(w >= 0 && h >= 0);
110 if (!fScissorLoc.equals(x, y) || !fScissorSize.equals(w, h)) {
111 fScissorLoc.set(x, y);
112 fScissorSize.set(w, h);
113 glScissor(x, y, w, h);
114 }
115}
116
117void SkGLState::pointSize(float x) {
118 if (fPointSize != x) {
119 fPointSize = x;
120 glPointSize(x);
121 }
122}
123
124void SkGLState::lineWidth(float x) {
125 if (fLineWidth != x) {
126 fLineWidth = x;
127 glLineWidth(x);
128 }
129}
130
131void SkGLState::blendFunc(GLenum src, GLenum dst) {
132 if (fSrcBlend != src || fDstBlend != dst) {
133 fSrcBlend = src;
134 fDstBlend = dst;
135 glBlendFunc(src, dst);
136 }
137}
138
139///////////////////////////////////////////////////////////////////////////////
140
141#ifdef SK_GL_HAS_COLOR4UB
142 static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) {
143 glColor4ub(r, g, b, a);
144 }
145#else
146 static inline SkFixed byte2fixed(U8CPU value) {
147 return ((value << 8) | value) + (value >> 7);
148 }
149
150 static inline void gl_pmcolor(U8CPU r, U8CPU g, U8CPU b, U8CPU a) {
151 glColor4x(byte2fixed(r), byte2fixed(g), byte2fixed(b), byte2fixed(a));
152 }
153#endif
154
155void SkGLState::pmColor(SkPMColor c) {
156 if (fPMColor != c) {
157 fPMColor = c;
158 gl_pmcolor(SkGetPackedR32(c), SkGetPackedG32(c),
159 SkGetPackedB32(c), SkGetPackedA32(c));
160 }
161}
162