1 /**
2 **
3 ** Copyright 2010, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 ** http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17
18 #include "pixelflinger2.h"
19
20 #include "src/talloc/hieralloc.h"
21 #include <string>
22
gglError(unsigned error)23 void gglError(unsigned error)
24 {
25 std::string str;
26 if (GL_NO_ERROR == error)
27 return;
28 LOGD("\n*\n*\n pf2: gglError 0x%.4X \n*\n*\n", error);
29 assert(0);
30 }
31
DepthRangef(GGLInterface * iface,GLclampf zNear,GLclampf zFar)32 static void DepthRangef(GGLInterface * iface, GLclampf zNear, GLclampf zFar)
33 {
34 GGL_GET_CONTEXT(ctx, iface);
35 ctx->viewport.n = VectorComp_t_CTR((zNear + zFar) / 2);
36 ctx->viewport.f = VectorComp_t_CTR((zFar - zNear) / 2);
37 }
38
Viewport(GGLInterface * iface,GLint x,GLint y,GLsizei width,GLsizei height)39 static void Viewport(GGLInterface * iface, GLint x, GLint y, GLsizei width, GLsizei height)
40 {
41 GGL_GET_CONTEXT(ctx, iface);
42 ctx->viewport.x = VectorComp_t_CTR(x + width / 2);
43 ctx->viewport.y = VectorComp_t_CTR(y + height / 2);
44 ctx->viewport.w = VectorComp_t_CTR(width / 2);
45 ctx->viewport.h = VectorComp_t_CTR(height / 2);
46 }
47
CullFace(GGLInterface * iface,GLenum mode)48 static void CullFace(GGLInterface * iface, GLenum mode)
49 {
50 GGL_GET_CONTEXT(ctx, iface);
51 if (GL_FRONT > mode || GL_FRONT_AND_BACK < mode)
52 gglError(GL_INVALID_ENUM);
53 else
54 ctx->cullState.cullFace = mode - GL_FRONT;
55 }
56
FrontFace(GGLInterface * iface,GLenum mode)57 static void FrontFace(GGLInterface * iface, GLenum mode)
58 {
59 GGL_GET_CONTEXT(ctx, iface);
60 if (GL_CW > mode || GL_CCW < mode)
61 gglError(GL_INVALID_ENUM);
62 else
63 ctx->cullState.frontFace = mode - GL_CW;
64 }
65
BlendColor(GGLInterface * iface,GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)66 static void BlendColor(GGLInterface * iface, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
67 {
68 GGL_GET_CONTEXT(ctx, iface);
69 ctx->state.blendState.color[0] = MIN2(MAX2(red * 255, 0.0f), 255.0f);
70 ctx->state.blendState.color[1] = MIN2(MAX2(green * 255, 0.0f), 255.0f);
71 ctx->state.blendState.color[2] = MIN2(MAX2(blue * 255, 0.0f), 255.0f);
72 ctx->state.blendState.color[3] = MIN2(MAX2(alpha * 255, 0.0f), 255.0f);
73 SetShaderVerifyFunctions(iface);
74 }
75
BlendEquationSeparate(GGLInterface * iface,GLenum modeRGB,GLenum modeAlpha)76 static void BlendEquationSeparate(GGLInterface * iface, GLenum modeRGB, GLenum modeAlpha)
77 {
78 GGL_GET_CONTEXT(ctx, iface);
79 if (GL_FUNC_ADD != modeRGB && (GL_FUNC_SUBTRACT > modeRGB ||
80 GL_FUNC_REVERSE_SUBTRACT < modeRGB))
81 return gglError(GL_INVALID_ENUM);
82 if (GL_FUNC_ADD != modeRGB && (GL_FUNC_SUBTRACT > modeRGB ||
83 GL_FUNC_REVERSE_SUBTRACT < modeRGB))
84 return gglError(GL_INVALID_ENUM);
85 ctx->state.blendState.ce = (GGLBlendState::GGLBlendFunc)(modeRGB - GL_FUNC_ADD);
86 ctx->state.blendState.ae = (GGLBlendState::GGLBlendFunc)(modeAlpha - GL_FUNC_ADD);
87 SetShaderVerifyFunctions(iface);
88 }
89
GLBlendFactor(const GLenum factor)90 static inline GGLBlendState::GGLBlendFactor GLBlendFactor(const GLenum factor)
91 {
92 #define SWITCH_LINE(c) case c: return GGLBlendState::G##c;
93 switch (factor)
94 {
95 SWITCH_LINE(GL_ZERO);
96 SWITCH_LINE(GL_ONE);
97 SWITCH_LINE(GL_SRC_COLOR);
98 SWITCH_LINE(GL_ONE_MINUS_SRC_COLOR);
99 SWITCH_LINE(GL_DST_COLOR);
100 SWITCH_LINE(GL_ONE_MINUS_DST_COLOR);
101 SWITCH_LINE(GL_SRC_ALPHA);
102 SWITCH_LINE(GL_ONE_MINUS_SRC_ALPHA);
103 SWITCH_LINE(GL_DST_ALPHA);
104 SWITCH_LINE(GL_ONE_MINUS_DST_ALPHA);
105 SWITCH_LINE(GL_SRC_ALPHA_SATURATE);
106 SWITCH_LINE(GL_CONSTANT_COLOR);
107 SWITCH_LINE(GL_ONE_MINUS_CONSTANT_COLOR);
108 SWITCH_LINE(GL_CONSTANT_ALPHA);
109 SWITCH_LINE(GL_ONE_MINUS_CONSTANT_ALPHA);
110 default: assert(0); return GGLBlendState::GGL_ZERO;
111 }
112 #undef SWITCH_LINE
113 }
114
BlendFuncSeparate(GGLInterface * iface,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)115 static void BlendFuncSeparate(GGLInterface * iface, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
116 {
117 GGL_GET_CONTEXT(ctx, iface);
118 if (GL_ZERO != srcRGB && GL_ONE != srcRGB &&
119 (GL_SRC_COLOR > srcRGB || GL_SRC_ALPHA_SATURATE < srcRGB) &&
120 (GL_CONSTANT_COLOR > srcRGB || GL_ONE_MINUS_CONSTANT_ALPHA < srcRGB))
121 return gglError(GL_INVALID_ENUM);
122 if (GL_ZERO != srcAlpha && GL_ONE != srcAlpha &&
123 (GL_SRC_COLOR > srcAlpha || GL_SRC_ALPHA_SATURATE < srcAlpha) &&
124 (GL_CONSTANT_COLOR > dstRGB || GL_ONE_MINUS_CONSTANT_ALPHA < dstRGB))
125 return gglError(GL_INVALID_ENUM);
126 if (GL_ZERO != dstRGB && GL_ONE != dstRGB &&
127 (GL_SRC_COLOR > dstRGB || GL_ONE_MINUS_DST_COLOR < dstRGB) && // GL_SRC_ALPHA_SATURATE only for source
128 (GL_CONSTANT_COLOR > dstRGB || GL_ONE_MINUS_CONSTANT_ALPHA < dstRGB))
129 return gglError(GL_INVALID_ENUM);
130 if (GL_ZERO != dstAlpha && GL_ONE != dstAlpha &&
131 (GL_SRC_COLOR > dstAlpha || GL_ONE_MINUS_DST_COLOR < dstAlpha) &&
132 (GL_CONSTANT_COLOR > dstRGB || GL_ONE_MINUS_CONSTANT_ALPHA < dstRGB))
133 return gglError(GL_INVALID_ENUM);
134 if (srcAlpha == GL_SRC_ALPHA_SATURATE) // it's just 1 instead of min(sa, 1 - da) for alpha channel
135 srcAlpha = GL_ONE;
136 // in c++ it's templated function for color and alpha,
137 // so it requires setting srcAlpha to GL_ONE to run template again only for alpha
138 ctx->state.blendState.scf = GLBlendFactor(srcRGB);
139 ctx->state.blendState.saf = GLBlendFactor(srcAlpha);
140 ctx->state.blendState.dcf = GLBlendFactor(dstRGB);
141 ctx->state.blendState.daf = GLBlendFactor(dstAlpha);
142 SetShaderVerifyFunctions(iface);
143
144 }
145
EnableDisable(GGLInterface * iface,GLenum cap,GLboolean enable)146 static void EnableDisable(GGLInterface * iface, GLenum cap, GLboolean enable)
147 {
148 GGL_GET_CONTEXT(ctx, iface);
149 bool changed = false;
150 switch (cap) {
151 case GL_BLEND:
152 changed |= ctx->state.blendState.enable ^ enable;
153 ctx->state.blendState.enable = enable;
154 break;
155 case GL_CULL_FACE:
156 changed |= ctx->cullState.enable ^ enable;
157 ctx->cullState.enable = enable;
158 break;
159 case GL_DEPTH_TEST:
160 changed |= ctx->state.bufferState.depthTest ^ enable;
161 ctx->state.bufferState.depthTest = enable;
162 break;
163 case GL_STENCIL_TEST:
164 changed |= ctx->state.bufferState.stencilTest ^ enable;
165 ctx->state.bufferState.stencilTest = enable;
166 break;
167 case GL_DITHER:
168 // LOGD("pf2: EnableDisable GL_DITHER \n");
169 break;
170 case GL_SCISSOR_TEST:
171 // LOGD("pf2: EnableDisable GL_SCISSOR_TEST \n");
172 break;
173 case GL_TEXTURE_2D:
174 // LOGD("pf2: EnableDisable GL_SCISSOR_TEST %d", enable);
175 break;
176 default:
177 LOGD("pf2: EnableDisable 0x%.4X causes GL_INVALID_ENUM (maybe not implemented or ES 1.0) \n", cap);
178 // gglError(GL_INVALID_ENUM);
179 assert(0);
180 break;
181 }
182 if (changed)
183 SetShaderVerifyFunctions(iface);
184 }
185
InitializeGGLState(GGLInterface * iface)186 void InitializeGGLState(GGLInterface * iface)
187 {
188 #if USE_DUAL_THREAD
189 reinterpret_cast<GGLContext *>(iface)->worker = GGLContext::Worker();
190 #endif
191 iface->DepthRangef = DepthRangef;
192 iface->Viewport = Viewport;
193 iface->CullFace = CullFace;
194 iface->FrontFace = FrontFace;
195 iface->BlendColor = BlendColor;
196 iface->BlendEquationSeparate = BlendEquationSeparate;
197 iface->BlendFuncSeparate = BlendFuncSeparate;
198 iface->EnableDisable = EnableDisable;
199
200 InitializeBufferFunctions(iface);
201 InitializeRasterFunctions(iface);
202 InitializeScanLineFunctions(iface);
203 InitializeShaderFunctions(iface);
204 InitializeTextureFunctions(iface);
205
206 iface->EnableDisable(iface, GL_DEPTH_TEST, false);
207 iface->DepthFunc(iface, GL_LESS);
208 iface->ClearColor(iface, 0, 0, 0, 0);
209 iface->ClearDepthf(iface, 1.0f);
210
211 iface->EnableDisable(iface, GL_STENCIL_TEST, false);
212 iface->StencilFuncSeparate(iface, GL_FRONT_AND_BACK, GL_ALWAYS, 0, 0xff);
213 iface->StencilOpSeparate(iface, GL_FRONT_AND_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
214
215 iface->FrontFace(iface, GL_CCW);
216 iface->CullFace(iface, GL_BACK);
217 iface->EnableDisable(iface, GL_CULL_FACE, false);
218
219 iface->EnableDisable(iface, GL_BLEND, false);
220 iface->BlendColor(iface, 0, 0, 0, 0);
221 iface->BlendEquationSeparate(iface, GL_FUNC_ADD, GL_FUNC_ADD);
222 iface->BlendFuncSeparate(iface, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO);
223
224 for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
225 iface->SetSampler(iface, i, NULL);
226
227 iface->SetBuffer(iface, GL_COLOR_BUFFER_BIT, NULL);
228 iface->SetBuffer(iface, GL_DEPTH_BUFFER_BIT, NULL);
229 iface->SetBuffer(iface, GL_STENCIL_BUFFER_BIT, NULL);
230
231 SetShaderVerifyFunctions(iface);
232 }
233
CreateGGLInterface()234 GGLInterface * CreateGGLInterface()
235 {
236 GGLContext * const ctx = (GGLContext *)calloc(1, sizeof(GGLContext));
237 if (!ctx)
238 return NULL;
239 assert((void *)ctx == (void *)&ctx->interface);
240
241 //_glapi_set_context(ctx->glCtx);
242 //_mesa_init_constants(&Const);
243
244 puts("InitializeGGLState");
245 InitializeGGLState(&ctx->interface);
246 return &ctx->interface;
247 }
248
UninitializeGGLState(GGLInterface * iface)249 void UninitializeGGLState(GGLInterface * iface)
250 {
251 #if USE_DUAL_THREAD
252 reinterpret_cast<GGLContext *>(iface)->worker.~Worker();
253 #endif
254 DestroyShaderFunctions(iface);
255
256 #if USE_LLVM_TEXTURE_SAMPLER
257 puts("USE_LLVM_TEXTURE_SAMPLER");
258 #endif
259 #if USE_LLVM_SCANLINE
260 puts("USE_LLVM_SCANLINE");
261 #endif
262 #if USE_LLVM_EXECUTIONENGINE
263 puts("USE_LLVM_EXECUTIONENGINE");
264 #endif
265 #if USE_DUAL_THREAD
266 puts("USE_DUAL_THREAD");
267 #endif
268 hieralloc_report_brief(NULL, stdout);
269 }
270
DestroyGGLInterface(GGLInterface * iface)271 void DestroyGGLInterface(GGLInterface * iface)
272 {
273 GGLContext * const ctx = reinterpret_cast<GGLContext *>(iface);
274 UninitializeGGLState(iface);
275 free(ctx);
276 }
277