Home | History | Annotate | Download | only in scenegraph
      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, &currentCam->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, &currentCam->view);
    132         break;
    133     case SHADER_PARAM_TRANSFORM_PROJ:
    134         rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->proj);
    135         break;
    136     case SHADER_PARAM_TRANSFORM_VIEW_PROJ:
    137         rsMatrixLoad((rs_matrix4x4*)dataPtr, &currentCam->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, &currentCam->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, &currentCam->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