/** ** ** Copyright 2010, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #include "pixelflinger2.h" #include "src/talloc/hieralloc.h" #include <string> void gglError(unsigned error) { std::string str; if (GL_NO_ERROR == error) return; ALOGD("\n*\n*\n pf2: gglError 0x%.4X \n*\n*\n", error); assert(0); } static void DepthRangef(GGLInterface * iface, GLclampf zNear, GLclampf zFar) { GGL_GET_CONTEXT(ctx, iface); ctx->viewport.n = VectorComp_t_CTR((zNear + zFar) / 2); ctx->viewport.f = VectorComp_t_CTR((zFar - zNear) / 2); } static void Viewport(GGLInterface * iface, GLint x, GLint y, GLsizei width, GLsizei height) { GGL_GET_CONTEXT(ctx, iface); ctx->viewport.x = VectorComp_t_CTR(x + width / 2); ctx->viewport.y = VectorComp_t_CTR(y + height / 2); ctx->viewport.w = VectorComp_t_CTR(width / 2); ctx->viewport.h = VectorComp_t_CTR(height / 2); } static void CullFace(GGLInterface * iface, GLenum mode) { GGL_GET_CONTEXT(ctx, iface); if (GL_FRONT > mode || GL_FRONT_AND_BACK < mode) gglError(GL_INVALID_ENUM); else ctx->cullState.cullFace = mode - GL_FRONT; } static void FrontFace(GGLInterface * iface, GLenum mode) { GGL_GET_CONTEXT(ctx, iface); if (GL_CW > mode || GL_CCW < mode) gglError(GL_INVALID_ENUM); else ctx->cullState.frontFace = mode - GL_CW; } static void BlendColor(GGLInterface * iface, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { GGL_GET_CONTEXT(ctx, iface); ctx->state.blendState.color[0] = MIN2(MAX2(red * 255, 0.0f), 255.0f); ctx->state.blendState.color[1] = MIN2(MAX2(green * 255, 0.0f), 255.0f); ctx->state.blendState.color[2] = MIN2(MAX2(blue * 255, 0.0f), 255.0f); ctx->state.blendState.color[3] = MIN2(MAX2(alpha * 255, 0.0f), 255.0f); SetShaderVerifyFunctions(iface); } static void BlendEquationSeparate(GGLInterface * iface, GLenum modeRGB, GLenum modeAlpha) { GGL_GET_CONTEXT(ctx, iface); if (GL_FUNC_ADD != modeRGB && (GL_FUNC_SUBTRACT > modeRGB || GL_FUNC_REVERSE_SUBTRACT < modeRGB)) return gglError(GL_INVALID_ENUM); if (GL_FUNC_ADD != modeRGB && (GL_FUNC_SUBTRACT > modeRGB || GL_FUNC_REVERSE_SUBTRACT < modeRGB)) return gglError(GL_INVALID_ENUM); ctx->state.blendState.ce = (GGLBlendState::GGLBlendFunc)(modeRGB - GL_FUNC_ADD); ctx->state.blendState.ae = (GGLBlendState::GGLBlendFunc)(modeAlpha - GL_FUNC_ADD); SetShaderVerifyFunctions(iface); } static inline GGLBlendState::GGLBlendFactor GLBlendFactor(const GLenum factor) { #define SWITCH_LINE(c) case c: return GGLBlendState::G##c; switch (factor) { SWITCH_LINE(GL_ZERO); SWITCH_LINE(GL_ONE); SWITCH_LINE(GL_SRC_COLOR); SWITCH_LINE(GL_ONE_MINUS_SRC_COLOR); SWITCH_LINE(GL_DST_COLOR); SWITCH_LINE(GL_ONE_MINUS_DST_COLOR); SWITCH_LINE(GL_SRC_ALPHA); SWITCH_LINE(GL_ONE_MINUS_SRC_ALPHA); SWITCH_LINE(GL_DST_ALPHA); SWITCH_LINE(GL_ONE_MINUS_DST_ALPHA); SWITCH_LINE(GL_SRC_ALPHA_SATURATE); SWITCH_LINE(GL_CONSTANT_COLOR); SWITCH_LINE(GL_ONE_MINUS_CONSTANT_COLOR); SWITCH_LINE(GL_CONSTANT_ALPHA); SWITCH_LINE(GL_ONE_MINUS_CONSTANT_ALPHA); default: assert(0); return GGLBlendState::GGL_ZERO; } #undef SWITCH_LINE } static void BlendFuncSeparate(GGLInterface * iface, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { GGL_GET_CONTEXT(ctx, iface); if (GL_ZERO != srcRGB && GL_ONE != srcRGB && (GL_SRC_COLOR > srcRGB || GL_SRC_ALPHA_SATURATE < srcRGB) && (GL_CONSTANT_COLOR > srcRGB || GL_ONE_MINUS_CONSTANT_ALPHA < srcRGB)) return gglError(GL_INVALID_ENUM); if (GL_ZERO != srcAlpha && GL_ONE != srcAlpha && (GL_SRC_COLOR > srcAlpha || GL_SRC_ALPHA_SATURATE < srcAlpha) && (GL_CONSTANT_COLOR > dstRGB || GL_ONE_MINUS_CONSTANT_ALPHA < dstRGB)) return gglError(GL_INVALID_ENUM); if (GL_ZERO != dstRGB && GL_ONE != dstRGB && (GL_SRC_COLOR > dstRGB || GL_ONE_MINUS_DST_COLOR < dstRGB) && // GL_SRC_ALPHA_SATURATE only for source (GL_CONSTANT_COLOR > dstRGB || GL_ONE_MINUS_CONSTANT_ALPHA < dstRGB)) return gglError(GL_INVALID_ENUM); if (GL_ZERO != dstAlpha && GL_ONE != dstAlpha && (GL_SRC_COLOR > dstAlpha || GL_ONE_MINUS_DST_COLOR < dstAlpha) && (GL_CONSTANT_COLOR > dstRGB || GL_ONE_MINUS_CONSTANT_ALPHA < dstRGB)) return gglError(GL_INVALID_ENUM); if (srcAlpha == GL_SRC_ALPHA_SATURATE) // it's just 1 instead of min(sa, 1 - da) for alpha channel srcAlpha = GL_ONE; // in c++ it's templated function for color and alpha, // so it requires setting srcAlpha to GL_ONE to run template again only for alpha ctx->state.blendState.scf = GLBlendFactor(srcRGB); ctx->state.blendState.saf = GLBlendFactor(srcAlpha); ctx->state.blendState.dcf = GLBlendFactor(dstRGB); ctx->state.blendState.daf = GLBlendFactor(dstAlpha); SetShaderVerifyFunctions(iface); } static void EnableDisable(GGLInterface * iface, GLenum cap, GLboolean enable) { GGL_GET_CONTEXT(ctx, iface); bool changed = false; switch (cap) { case GL_BLEND: changed |= ctx->state.blendState.enable ^ enable; ctx->state.blendState.enable = enable; break; case GL_CULL_FACE: changed |= ctx->cullState.enable ^ enable; ctx->cullState.enable = enable; break; case GL_DEPTH_TEST: changed |= ctx->state.bufferState.depthTest ^ enable; ctx->state.bufferState.depthTest = enable; break; case GL_STENCIL_TEST: changed |= ctx->state.bufferState.stencilTest ^ enable; ctx->state.bufferState.stencilTest = enable; break; case GL_DITHER: // ALOGD("pf2: EnableDisable GL_DITHER \n"); break; case GL_SCISSOR_TEST: // ALOGD("pf2: EnableDisable GL_SCISSOR_TEST \n"); break; case GL_TEXTURE_2D: // ALOGD("pf2: EnableDisable GL_SCISSOR_TEST %d", enable); break; default: ALOGD("pf2: EnableDisable 0x%.4X causes GL_INVALID_ENUM (maybe not implemented or ES 1.0) \n", cap); // gglError(GL_INVALID_ENUM); assert(0); break; } if (changed) SetShaderVerifyFunctions(iface); } void InitializeGGLState(GGLInterface * iface) { #if USE_DUAL_THREAD reinterpret_cast<GGLContext *>(iface)->worker = GGLContext::Worker(); #endif iface->DepthRangef = DepthRangef; iface->Viewport = Viewport; iface->CullFace = CullFace; iface->FrontFace = FrontFace; iface->BlendColor = BlendColor; iface->BlendEquationSeparate = BlendEquationSeparate; iface->BlendFuncSeparate = BlendFuncSeparate; iface->EnableDisable = EnableDisable; InitializeBufferFunctions(iface); InitializeRasterFunctions(iface); InitializeScanLineFunctions(iface); InitializeShaderFunctions(iface); InitializeTextureFunctions(iface); iface->EnableDisable(iface, GL_DEPTH_TEST, false); iface->DepthFunc(iface, GL_LESS); iface->ClearColor(iface, 0, 0, 0, 0); iface->ClearDepthf(iface, 1.0f); iface->EnableDisable(iface, GL_STENCIL_TEST, false); iface->StencilFuncSeparate(iface, GL_FRONT_AND_BACK, GL_ALWAYS, 0, 0xff); iface->StencilOpSeparate(iface, GL_FRONT_AND_BACK, GL_KEEP, GL_KEEP, GL_KEEP); iface->FrontFace(iface, GL_CCW); iface->CullFace(iface, GL_BACK); iface->EnableDisable(iface, GL_CULL_FACE, false); iface->EnableDisable(iface, GL_BLEND, false); iface->BlendColor(iface, 0, 0, 0, 0); iface->BlendEquationSeparate(iface, GL_FUNC_ADD, GL_FUNC_ADD); iface->BlendFuncSeparate(iface, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) iface->SetSampler(iface, i, NULL); iface->SetBuffer(iface, GL_COLOR_BUFFER_BIT, NULL); iface->SetBuffer(iface, GL_DEPTH_BUFFER_BIT, NULL); iface->SetBuffer(iface, GL_STENCIL_BUFFER_BIT, NULL); SetShaderVerifyFunctions(iface); } GGLInterface * CreateGGLInterface() { GGLContext * const ctx = (GGLContext *)calloc(1, sizeof(GGLContext)); if (!ctx) return NULL; assert((void *)ctx == (void *)&ctx->interface); //_glapi_set_context(ctx->glCtx); //_mesa_init_constants(&Const); puts("InitializeGGLState"); InitializeGGLState(&ctx->interface); return &ctx->interface; } void UninitializeGGLState(GGLInterface * iface) { #if USE_DUAL_THREAD reinterpret_cast<GGLContext *>(iface)->worker.~Worker(); #endif DestroyShaderFunctions(iface); #if USE_LLVM_TEXTURE_SAMPLER puts("USE_LLVM_TEXTURE_SAMPLER"); #endif #if USE_LLVM_SCANLINE puts("USE_LLVM_SCANLINE"); #endif #if USE_LLVM_EXECUTIONENGINE puts("USE_LLVM_EXECUTIONENGINE"); #endif #if USE_DUAL_THREAD puts("USE_DUAL_THREAD"); #endif hieralloc_report_brief(NULL, stdout); } void DestroyGGLInterface(GGLInterface * iface) { GGLContext * const ctx = reinterpret_cast<GGLContext *>(iface); UninitializeGGLState(iface); free(ctx); }