| /* |
| * 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; |
| } |
| |
| |