| /* |
| * Copyright (C) 2011-2012 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. |
| */ |
| |
| #ifndef ANDROID_RSD_SHADER_CACHE_H |
| #define ANDROID_RSD_SHADER_CACHE_H |
| |
| namespace android { |
| namespace renderscript { |
| |
| class Context; |
| |
| } |
| } |
| |
| |
| #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB) |
| #include <utils/String8.h> |
| #include <utils/Vector.h> |
| #else |
| #include "rsUtils.h" |
| #endif |
| class RsdShader; |
| |
| // --------------------------------------------------------------------------- |
| |
| // An element is a group of Components that occupies one cell in a structure. |
| class RsdShaderCache { |
| public: |
| RsdShaderCache(); |
| virtual ~RsdShaderCache(); |
| |
| void setActiveVertex(RsdShader *pv) { |
| mVertexDirty = true; |
| mVertex = pv; |
| } |
| |
| void setActiveFragment(RsdShader *pf) { |
| mFragmentDirty = true; |
| mFragment = pf; |
| } |
| |
| bool setup(const android::renderscript::Context *rsc); |
| |
| void cleanupVertex(RsdShader *s); |
| void cleanupFragment(RsdShader *s); |
| |
| void cleanupAll(); |
| |
| int32_t vtxAttribSlot(const android::String8 &attrName) const; |
| int32_t vtxUniformSlot(uint32_t a) const {return mCurrent->vtxUniforms[a].slot;} |
| uint32_t vtxUniformSize(uint32_t a) const {return mCurrent->vtxUniforms[a].arraySize;} |
| int32_t fragUniformSlot(uint32_t a) const {return mCurrent->fragUniforms[a].slot;} |
| uint32_t fragUniformSize(uint32_t a) const {return mCurrent->fragUniforms[a].arraySize;} |
| |
| protected: |
| bool link(const android::renderscript::Context *rsc); |
| bool mFragmentDirty; |
| bool mVertexDirty; |
| RsdShader *mVertex; |
| RsdShader *mFragment; |
| |
| struct UniformQueryData { |
| char *name; |
| uint32_t nameLength; |
| int32_t writtenLength; |
| int32_t arraySize; |
| uint32_t type; |
| explicit UniformQueryData(uint32_t maxName) { |
| name = nullptr; |
| nameLength = maxName; |
| if (nameLength > 0 ) { |
| name = new char[nameLength]; |
| } |
| } |
| ~UniformQueryData() { |
| if (name != nullptr) { |
| delete[] name; |
| name = nullptr; |
| } |
| } |
| }; |
| struct UniformData { |
| int32_t slot; |
| uint32_t arraySize; |
| }; |
| struct AttrData { |
| int32_t slot; |
| const char* name; |
| }; |
| struct ProgramEntry { |
| ProgramEntry(uint32_t numVtxAttr, uint32_t numVtxUnis, |
| uint32_t numFragUnis) : vtx(0), frag(0), program(0), vtxAttrCount(0), |
| vtxAttrs(0), vtxUniforms(0), fragUniforms(0), |
| fragUniformIsSTO(0) { |
| vtxAttrCount = numVtxAttr; |
| if (numVtxAttr) { |
| vtxAttrs = new AttrData[numVtxAttr]; |
| } |
| if (numVtxUnis) { |
| vtxUniforms = new UniformData[numVtxUnis]; |
| } |
| if (numFragUnis) { |
| fragUniforms = new UniformData[numFragUnis]; |
| fragUniformIsSTO = new bool[numFragUnis]; |
| } |
| } |
| ~ProgramEntry() { |
| if (vtxAttrs) { |
| delete[] vtxAttrs; |
| vtxAttrs = nullptr; |
| } |
| if (vtxUniforms) { |
| delete[] vtxUniforms; |
| vtxUniforms = nullptr; |
| } |
| if (fragUniforms) { |
| delete[] fragUniforms; |
| fragUniforms = nullptr; |
| } |
| if (fragUniformIsSTO) { |
| delete[] fragUniformIsSTO; |
| fragUniformIsSTO = nullptr; |
| } |
| } |
| uint32_t vtx; |
| uint32_t frag; |
| uint32_t program; |
| uint32_t vtxAttrCount; |
| AttrData *vtxAttrs; |
| UniformData *vtxUniforms; |
| UniformData *fragUniforms; |
| bool *fragUniformIsSTO; |
| }; |
| android::Vector<ProgramEntry*> mEntries; |
| ProgramEntry *mCurrent; |
| |
| bool hasArrayUniforms(RsdShader *vtx, RsdShader *frag); |
| void populateUniformData(RsdShader *prog, uint32_t linkedID, UniformData *data); |
| void updateUniformArrayData(const android::renderscript::Context *rsc, |
| RsdShader *prog, uint32_t linkedID, |
| UniformData *data, const char* logTag, |
| UniformQueryData **uniformList, uint32_t uniListSize); |
| }; |
| |
| |
| #endif //ANDROID_RSD_SHADER_CACHE_H |
| |
| |
| |
| |