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 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 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 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 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 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 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 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 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 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 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 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 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 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 271 void DestroyGGLInterface(GGLInterface * iface) 272 { 273 GGLContext * const ctx = reinterpret_cast<GGLContext *>(iface); 274 UninitializeGGLState(iface); 275 free(ctx); 276 } 277