Home | History | Annotate | Download | only in pixelflinger2
      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    ALOGD("\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 //      ALOGD("pf2: EnableDisable GL_DITHER \n");
    169       break;
    170    case GL_SCISSOR_TEST:
    171 //      ALOGD("pf2: EnableDisable GL_SCISSOR_TEST \n");
    172       break;
    173    case GL_TEXTURE_2D:
    174 //      ALOGD("pf2: EnableDisable GL_SCISSOR_TEST %d", enable);
    175       break;
    176    default:
    177       ALOGD("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