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
23void 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
32static 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
39static 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
48static 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
57static 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
66static 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
76static 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
90static 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
115static 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
146static 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
186void 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
234GGLInterface * 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
249void 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
271void DestroyGGLInterface(GGLInterface * iface)
272{
273   GGLContext * const ctx = reinterpret_cast<GGLContext *>(iface);
274   UninitializeGGLState(iface);
275   free(ctx);
276}
277