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 22 static 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 47 48 static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) { 49 #ifdef DEBUG_PARAMS 50 rsDebug("Writing value ", *input); 51 rsDebug("Writing vec size ", vecSize); 52 #endif // DEBUG_PARAMS 53 54 switch (vecSize) { 55 case 1: 56 *ptr = input->x; 57 break; 58 case 2: 59 *((float2*)ptr) = (*input).xy; 60 break; 61 case 3: 62 *((float3*)ptr) = (*input).xyz; 63 break; 64 case 4: 65 *((float4*)ptr) = *input; 66 break; 67 } 68 } 69 70 static bool processParam(SgShaderParam *p, SgShaderParamData *pData, 71 uint8_t *constantBuffer, 72 const SgCamera *currentCam, 73 SgFragmentShader *shader) { 74 bool isDataOnly = (pData->type > SHADER_PARAM_DATA_ONLY); 75 const SgTransform *pTransform = NULL; 76 if (rsIsObject(pData->transform)) { 77 pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0); 78 } 79 80 if (isDataOnly) { 81 // If we are a transform param and our transform is unchanged, nothing to do 82 if (pTransform) { 83 if (p->transformTimestamp == pTransform->timestamp) { 84 return false; 85 } 86 p->transformTimestamp = pTransform->timestamp; 87 } else { 88 if (p->dataTimestamp == pData->timestamp) { 89 return false; 90 } 91 p->dataTimestamp = pData->timestamp; 92 } 93 } 94 95 const SgLight *pLight = NULL; 96 if (rsIsObject(pData->light)) { 97 pLight = (const SgLight *)rsGetElementAt(pData->light, 0); 98 } 99 100 uint8_t *dataPtr = NULL; 101 const SgTexture *tex = NULL; 102 if (pData->type == SHADER_PARAM_TEXTURE) { 103 tex = rsGetElementAt(pData->texture, 0); 104 } else { 105 dataPtr = constantBuffer + p->bufferOffset; 106 } 107 108 switch (pData->type) { 109 case SHADER_PARAM_TEXTURE: 110 rsgBindTexture(shader->program, p->bufferOffset, tex->texture); 111 break; 112 case SHADER_PARAM_FLOAT4_DATA: 113 writeFloatData((float*)dataPtr, &pData->float_value, p->float_vecSize); 114 break; 115 case SHADER_PARAM_FLOAT4_CAMERA_POS: 116 writeFloatData((float*)dataPtr, ¤tCam->position, p->float_vecSize); 117 break; 118 case SHADER_PARAM_FLOAT4_CAMERA_DIR: break; 119 case SHADER_PARAM_FLOAT4_LIGHT_COLOR: 120 writeFloatData((float*)dataPtr, &pLight->color, p->float_vecSize); 121 break; 122 case SHADER_PARAM_FLOAT4_LIGHT_POS: 123 writeFloatData((float*)dataPtr, &pLight->position, p->float_vecSize); 124 break; 125 case SHADER_PARAM_FLOAT4_LIGHT_DIR: break; 126 127 case SHADER_PARAM_TRANSFORM_DATA: 128 rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); 129 break; 130 case SHADER_PARAM_TRANSFORM_VIEW: 131 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); 132 break; 133 case SHADER_PARAM_TRANSFORM_PROJ: 134 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->proj); 135 break; 136 case SHADER_PARAM_TRANSFORM_VIEW_PROJ: 137 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); 138 break; 139 case SHADER_PARAM_TRANSFORM_MODEL: 140 rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat); 141 break; 142 case SHADER_PARAM_TRANSFORM_MODEL_VIEW: 143 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view); 144 rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, 145 (rs_matrix4x4*)dataPtr, 146 &pTransform->globalMat); 147 break; 148 case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ: 149 rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj); 150 rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr, 151 (rs_matrix4x4*)dataPtr, 152 &pTransform->globalMat); 153 break; 154 } 155 return true; 156 } 157 158 static void processAllParams(rs_allocation shaderConst, 159 rs_allocation allParams, 160 const SgCamera *camera) { 161 if (rsIsObject(shaderConst)) { 162 uint8_t *constantBuffer = (uint8_t*)rsGetElementAt(shaderConst, 0); 163 164 int numParams = 0; 165 if (rsIsObject(allParams)) { 166 numParams = rsAllocationGetDimX(allParams); 167 } 168 bool updated = false; 169 for (int i = 0; i < numParams; i ++) { 170 SgShaderParam *current = (SgShaderParam*)rsGetElementAt(allParams, i); 171 SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0); 172 #ifdef DEBUG_PARAMS 173 debugParam(current, currentData); 174 #endif // DEBUG_PARAMS 175 updated = processParam(current, currentData, constantBuffer, camera, NULL) || updated; 176 } 177 } 178 } 179 180 static void processTextureParams(SgFragmentShader *shader) { 181 int numParams = 0; 182 if (rsIsObject(shader->shaderTextureParams)) { 183 numParams = rsAllocationGetDimX(shader->shaderTextureParams); 184 } 185 for (int i = 0; i < numParams; i ++) { 186 SgShaderParam *current = (SgShaderParam*)rsGetElementAt(shader->shaderTextureParams, i); 187 SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0); 188 #ifdef DEBUG_PARAMS 189 debugParam(current, currentData); 190 #endif // DEBUG_PARAMS 191 processParam(current, currentData, NULL, NULL, shader); 192 } 193 } 194