/* * Copyright (C) 2011 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 "rsdCore.h" #include "rsdProgramStore.h" #include "rsContext.h" #include "rsProgramStore.h" #include <GLES/gl.h> #include <GLES/glext.h> using namespace android; using namespace android::renderscript; struct DrvProgramStore { GLenum blendSrc; GLenum blendDst; bool blendEnable; GLenum depthFunc; bool depthTestEnable; }; bool rsdProgramStoreInit(const Context *rsc, const ProgramStore *ps) { DrvProgramStore *drv = (DrvProgramStore *)calloc(1, sizeof(DrvProgramStore)); if (drv == NULL) { return false; } ps->mHal.drv = drv; drv->depthTestEnable = true; switch (ps->mHal.state.depthFunc) { case RS_DEPTH_FUNC_ALWAYS: drv->depthTestEnable = false; drv->depthFunc = GL_ALWAYS; break; case RS_DEPTH_FUNC_LESS: drv->depthFunc = GL_LESS; break; case RS_DEPTH_FUNC_LEQUAL: drv->depthFunc = GL_LEQUAL; break; case RS_DEPTH_FUNC_GREATER: drv->depthFunc = GL_GREATER; break; case RS_DEPTH_FUNC_GEQUAL: drv->depthFunc = GL_GEQUAL; break; case RS_DEPTH_FUNC_EQUAL: drv->depthFunc = GL_EQUAL; break; case RS_DEPTH_FUNC_NOTEQUAL: drv->depthFunc = GL_NOTEQUAL; break; default: ALOGE("Unknown depth function."); goto error; } drv->blendEnable = true; if ((ps->mHal.state.blendSrc == RS_BLEND_SRC_ONE) && (ps->mHal.state.blendDst == RS_BLEND_DST_ZERO)) { drv->blendEnable = false; } switch (ps->mHal.state.blendSrc) { case RS_BLEND_SRC_ZERO: drv->blendSrc = GL_ZERO; break; case RS_BLEND_SRC_ONE: drv->blendSrc = GL_ONE; break; case RS_BLEND_SRC_DST_COLOR: drv->blendSrc = GL_DST_COLOR; break; case RS_BLEND_SRC_ONE_MINUS_DST_COLOR: drv->blendSrc = GL_ONE_MINUS_DST_COLOR; break; case RS_BLEND_SRC_SRC_ALPHA: drv->blendSrc = GL_SRC_ALPHA; break; case RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA: drv->blendSrc = GL_ONE_MINUS_SRC_ALPHA; break; case RS_BLEND_SRC_DST_ALPHA: drv->blendSrc = GL_DST_ALPHA; break; case RS_BLEND_SRC_ONE_MINUS_DST_ALPHA: drv->blendSrc = GL_ONE_MINUS_DST_ALPHA; break; case RS_BLEND_SRC_SRC_ALPHA_SATURATE: drv->blendSrc = GL_SRC_ALPHA_SATURATE; break; default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend src mode."); goto error; } switch (ps->mHal.state.blendDst) { case RS_BLEND_DST_ZERO: drv->blendDst = GL_ZERO; break; case RS_BLEND_DST_ONE: drv->blendDst = GL_ONE; break; case RS_BLEND_DST_SRC_COLOR: drv->blendDst = GL_SRC_COLOR; break; case RS_BLEND_DST_ONE_MINUS_SRC_COLOR: drv->blendDst = GL_ONE_MINUS_SRC_COLOR; break; case RS_BLEND_DST_SRC_ALPHA: drv->blendDst = GL_SRC_ALPHA; break; case RS_BLEND_DST_ONE_MINUS_SRC_ALPHA: drv->blendDst = GL_ONE_MINUS_SRC_ALPHA; break; case RS_BLEND_DST_DST_ALPHA: drv->blendDst = GL_DST_ALPHA; break; case RS_BLEND_DST_ONE_MINUS_DST_ALPHA: drv->blendDst = GL_ONE_MINUS_DST_ALPHA; break; default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend dst mode."); goto error; } return true; error: free(drv); ps->mHal.drv = NULL; return false; } void rsdProgramStoreSetActive(const Context *rsc, const ProgramStore *ps) { DrvProgramStore *drv = (DrvProgramStore *)ps->mHal.drv; RSD_CALL_GL(glColorMask, ps->mHal.state.colorRWriteEnable, ps->mHal.state.colorGWriteEnable, ps->mHal.state.colorBWriteEnable, ps->mHal.state.colorAWriteEnable); if (drv->blendEnable) { RSD_CALL_GL(glEnable, GL_BLEND); RSD_CALL_GL(glBlendFunc, drv->blendSrc, drv->blendDst); } else { RSD_CALL_GL(glDisable, GL_BLEND); } if (rsc->mUserSurfaceConfig.depthMin > 0) { RSD_CALL_GL(glDepthMask, ps->mHal.state.depthWriteEnable); if (drv->depthTestEnable || ps->mHal.state.depthWriteEnable) { RSD_CALL_GL(glEnable, GL_DEPTH_TEST); RSD_CALL_GL(glDepthFunc, drv->depthFunc); } else { RSD_CALL_GL(glDisable, GL_DEPTH_TEST); } } else { RSD_CALL_GL(glDepthMask, false); RSD_CALL_GL(glDisable, GL_DEPTH_TEST); } /* if (rsc->mUserSurfaceConfig.stencilMin > 0) { } else { glStencilMask(0); glDisable(GL_STENCIL_TEST); } */ if (ps->mHal.state.ditherEnable) { RSD_CALL_GL(glEnable, GL_DITHER); } else { RSD_CALL_GL(glDisable, GL_DITHER); } } void rsdProgramStoreDestroy(const Context *rsc, const ProgramStore *ps) { free(ps->mHal.drv); ps->mHal.drv = NULL; }