1// Copyright (C) 2012 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#pragma version(1) 16 17#pragma rs java_package_name(com.android.scenegraph) 18 19#include "scenegraph_objects.rsh" 20 21//#define DEBUG_PARAMS 22static inline void debugParam(SgShaderParam *p, SgShaderParamData *pData) { 23 rsDebug("____________ Param ____________", p); 24 printName(pData->paramName); 25 rsDebug("bufferOffset", p->bufferOffset); 26 rsDebug("type ", pData->type); 27 rsDebug("data timestamp ", pData->timestamp); 28 rsDebug("param timestamp", p->dataTimestamp); 29 30 const SgTransform *pTransform = NULL; 31 if (rsIsObject(pData->transform)) { 32 pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0); 33 34 rsDebug("transform", pTransform); 35 printName(pTransform->name); 36 rsDebug("timestamp", pTransform->timestamp); 37 rsDebug("param timestamp", p->transformTimestamp); 38 } 39 40 const SgLight *pLight = NULL; 41 if (rsIsObject(pData->light)) { 42 pLight = (const SgLight *)rsGetElementAt(pData->light, 0); 43 printLightInfo(pLight); 44 } 45} 46 47static inline void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { 48#ifdef DEBUG_PARAMS 49 rsDebug("Writing value ", *input); 50 rsDebug("Writing vec size ", vecSize); 51#endif // DEBUG_PARAMS 52 53 switch (vecSize) { 54 case 1: 55 *ptr = input->x; 56 break; 57 case 2: 58 *((float2*)ptr) = (*input).xy; 59 break; 60 case 3: 61 *((float3*)ptr) = (*input).xyz; 62 break; 63 case 4: 64 *((float4*)ptr) = *input; 65 break; 66 } 67} 68 69static inline bool processParam(SgShaderParam *p, SgShaderParamData *pData, 70 uint8_t *constantBuffer, 71 const SgCamera *currentCam, 72 SgFragmentShader *shader) { 73 bool isDataOnly = (pData->type > SHADER_PARAM_DATA_ONLY); 74 const SgTransform *pTransform = NULL; 75 if (rsIsObject(pData->transform)) { 76 pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0); 77 } 78 79 if (isDataOnly) { 80 // If we are a transform param and our transform is unchanged, nothing to do 81 if (pTransform) { 82 if (p->transformTimestamp == pTransform->timestamp) { 83 return false; 84 } 85 p->transformTimestamp = pTransform->timestamp; 86 } else { 87 if (p->dataTimestamp == pData->timestamp) { 88 return false; 89 } 90 p->dataTimestamp = pData->timestamp; 91 } 92 } 93 94 const SgLight *pLight = NULL; 95 if (rsIsObject(pData->light)) { 96 pLight = (const SgLight *)rsGetElementAt(pData->light, 0); 97 } 98 99 uint8_t *dataPtr = NULL; 100 const SgTexture *tex = NULL; 101 if (pData->type == SHADER_PARAM_TEXTURE) { 102 tex = rsGetElementAt(pData->texture, 0); 103 } else { 104 dataPtr = constantBuffer + p->bufferOffset; 105 } 106 107 switch (pData->type) { 108 case SHADER_PARAM_TEXTURE: 109 rsgBindTexture(shader->program, p->bufferOffset, tex->texture); 110 break; 111 case SHADER_PARAM_FLOAT4_DATA: 112 writeFloatData((float*)dataPtr, &pData->float_value, p->float_vecSize); 113 break; 114 case SHADER_PARAM_FLOAT4_CAMERA_POS: 115 writeFloatData((float*)dataPtr, ¤tCam->position, p->float_vecSize); 116 break; 117 case SHADER_PARAM_FLOAT4_CAMERA_DIR: break; 118 case SHADER_PARAM_FLOAT4_LIGHT_COLOR: 119 writeFloatData((float*)dataPtr, &pLight->color, p->float_vecSize); 120 break; 121 case SHADER_PARAM_FLOAT4_LIGHT_POS: 122 writeFloatData((float*)dataPtr, &pLight->position, p->float_vecSize); 123 break; 124 case SHADER_PARAM_FLOAT4_LIGHT_DIR: break; 125 126 case SHADER_PARAM_TRANSFORM_DATA: 127 rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); 128 break; 129 case SHADER_PARAM_TRANSFORM_VIEW: 130 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); 131 break; 132 case SHADER_PARAM_TRANSFORM_PROJ: 133 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->proj); 134 break; 135 case SHADER_PARAM_TRANSFORM_VIEW_PROJ: 136 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); 137 break; 138 case SHADER_PARAM_TRANSFORM_MODEL: 139 rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); 140 break; 141 case SHADER_PARAM_TRANSFORM_MODEL_VIEW: 142 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); 143 rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, 144 (rs_matrix4x4*)dataPtr, 145 &pTransform->globalMat); 146 break; 147 case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ: 148 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); 149 rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, 150 (rs_matrix4x4*)dataPtr, 151 &pTransform->globalMat); 152 break; 153 } 154 return true; 155} 156 157static inline void processAllParams(rs_allocation shaderConst, 158 rs_allocation allParams, 159 const SgCamera *camera) { 160 if (rsIsObject(shaderConst)) { 161 uint8_t *constantBuffer = (uint8_t*)rsGetElementAt(shaderConst, 0); 162 163 int numParams = 0; 164 if (rsIsObject(allParams)) { 165 numParams = rsAllocationGetDimX(allParams); 166 } 167 bool updated = false; 168 for (int i = 0; i < numParams; i ++) { 169 SgShaderParam *current = (SgShaderParam*)rsGetElementAt(allParams, i); 170 SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0); 171#ifdef DEBUG_PARAMS 172 debugParam(current, currentData); 173#endif // DEBUG_PARAMS 174 updated = processParam(current, currentData, constantBuffer, camera, NULL) || updated; 175 } 176 } 177} 178 179static inline void processTextureParams(SgFragmentShader *shader) { 180 int numParams = 0; 181 if (rsIsObject(shader->shaderTextureParams)) { 182 numParams = rsAllocationGetDimX(shader->shaderTextureParams); 183 } 184 for (int i = 0; i < numParams; i ++) { 185 SgShaderParam *current = (SgShaderParam*)rsGetElementAt(shader->shaderTextureParams, i); 186 SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0); 187#ifdef DEBUG_PARAMS 188 debugParam(current, currentData); 189#endif // DEBUG_PARAMS 190 processParam(current, currentData, NULL, NULL, shader); 191 } 192} 193