• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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