Home | History | Annotate | Download | only in rs
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "rsContext.h"
     18 #include "rsProgramVertex.h"
     19 #include "rsMatrix4x4.h"
     20 
     21 using android::renderscript::ProgramVertex;
     22 using android::renderscript::ProgramVertexState;
     23 
     24 ProgramVertex::ProgramVertex(Context *rsc, const char * shaderText, size_t shaderLength,
     25                              const char** textureNames, size_t textureNamesCount, const size_t *textureNamesLength,
     26 
     27                              const uintptr_t * params, size_t paramLength)
     28     : Program(rsc, shaderText, shaderLength, params, paramLength) {
     29     mRSC->mHal.funcs.vertex.init(mRSC, this, mUserShader, mUserShaderLen,
     30                                  textureNames, textureNamesCount, textureNamesLength);
     31 }
     32 
     33 ProgramVertex::~ProgramVertex() {
     34     mRSC->mHal.funcs.vertex.destroy(mRSC, this);
     35 }
     36 
     37 void ProgramVertex::setup(Context *rsc, ProgramVertexState *state) {
     38     if ((state->mLast.get() == this) && !mDirty) {
     39         return;
     40     }
     41 
     42     if (!isUserProgram()) {
     43         if (mHal.state.constants[0] == nullptr) {
     44             rsc->setError(RS_ERROR_FATAL_UNKNOWN,
     45                           "Unable to set fixed function emulation matrices because allocation is missing");
     46             return;
     47         }
     48         float *f = static_cast<float *>(rsc->mHal.funcs.allocation.lock1D(
     49                 rsc, mHal.state.constants[0]));
     50         Matrix4x4 mvp;
     51         mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
     52         Matrix4x4 t;
     53         t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
     54         mvp.multiply(&t);
     55         for (uint32_t i = 0; i < 16; i ++) {
     56             f[RS_PROGRAM_VERTEX_MVP_OFFSET + i] = mvp.m[i];
     57         }
     58         rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
     59     }
     60 
     61     state->mLast.set(this);
     62 
     63     rsc->mHal.funcs.vertex.setActive(rsc, this);
     64 }
     65 
     66 void ProgramVertex::setProjectionMatrix(Context *rsc, const rsc_Matrix *m) const {
     67     if (isUserProgram()) {
     68         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
     69                       "Attempting to set fixed function emulation matrix projection on user program");
     70         return;
     71     }
     72     if (mHal.state.constants[0] == nullptr) {
     73         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
     74                       "Unable to set fixed function emulation matrix projection because allocation is missing");
     75         return;
     76     }
     77     float *f = static_cast<float *>(rsc->mHal.funcs.allocation.lock1D(
     78                 rsc, mHal.state.constants[0]));
     79     memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
     80     mDirty = true;
     81     rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
     82 }
     83 
     84 void ProgramVertex::setModelviewMatrix(Context *rsc, const rsc_Matrix *m) const {
     85     if (isUserProgram()) {
     86         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
     87                       "Attempting to set fixed function emulation matrix modelview on user program");
     88         return;
     89     }
     90     if (mHal.state.constants[0] == nullptr) {
     91         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
     92                       "Unable to set fixed function emulation matrix modelview because allocation is missing");
     93         return;
     94     }
     95     float *f = static_cast<float *>(rsc->mHal.funcs.allocation.lock1D(
     96                 rsc, mHal.state.constants[0]));
     97     memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
     98     mDirty = true;
     99     rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
    100 }
    101 
    102 void ProgramVertex::setTextureMatrix(Context *rsc, const rsc_Matrix *m) const {
    103     if (isUserProgram()) {
    104         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
    105                       "Attempting to set fixed function emulation matrix texture on user program");
    106         return;
    107     }
    108     if (mHal.state.constants[0] == nullptr) {
    109         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
    110                       "Unable to set fixed function emulation matrix texture because allocation is missing");
    111         return;
    112     }
    113     float *f = static_cast<float *>(rsc->mHal.funcs.allocation.lock1D(
    114             rsc, mHal.state.constants[0]));
    115     memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
    116     mDirty = true;
    117     rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
    118 }
    119 
    120 void ProgramVertex::getProjectionMatrix(Context *rsc, rsc_Matrix *m) const {
    121     if (isUserProgram()) {
    122         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
    123                       "Attempting to get fixed function emulation matrix projection on user program");
    124         return;
    125     }
    126     if (mHal.state.constants[0] == nullptr) {
    127         rsc->setError(RS_ERROR_FATAL_UNKNOWN,
    128                       "Unable to get fixed function emulation matrix projection because allocation is missing");
    129         return;
    130     }
    131     float *f = static_cast<float *>(
    132             rsc->mHal.funcs.allocation.lock1D(rsc, mHal.state.constants[0]));
    133     memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix));
    134     rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
    135 }
    136 
    137 void ProgramVertex::transformToScreen(Context *rsc, float *v4out, const float *v3in) const {
    138     if (isUserProgram()) {
    139         return;
    140     }
    141     float *f = static_cast<float *>(
    142             rsc->mHal.funcs.allocation.lock1D(rsc, mHal.state.constants[0]));
    143     Matrix4x4 mvp;
    144     mvp.loadMultiply((Matrix4x4 *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET],
    145                      (Matrix4x4 *)&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
    146     mvp.vectorMultiply(v4out, v3in);
    147     rsc->mHal.funcs.allocation.unlock1D(rsc, mHal.state.constants[0]);
    148 }
    149 
    150 void ProgramVertex::serialize(Context *rsc, OStream *stream) const {
    151 }
    152 
    153 ProgramVertex *ProgramVertex::createFromStream(Context *rsc, IStream *stream) {
    154     return nullptr;
    155 }
    156 
    157 
    158 ///////////////////////////////////////////////////////////////////////
    159 
    160 ProgramVertexState::ProgramVertexState() {
    161 }
    162 
    163 ProgramVertexState::~ProgramVertexState() {
    164 }
    165 
    166 void ProgramVertexState::init(Context *rsc) {
    167     ObjectBaseRef<const Element> matrixElem = Element::createRef(rsc, RS_TYPE_MATRIX_4X4,
    168                                                                  RS_KIND_USER, false, 1);
    169     ObjectBaseRef<const Element> f2Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
    170                                                              RS_KIND_USER, false, 2);
    171     ObjectBaseRef<const Element> f3Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
    172                                                              RS_KIND_USER, false, 3);
    173     ObjectBaseRef<const Element> f4Elem = Element::createRef(rsc, RS_TYPE_FLOAT_32,
    174                                                              RS_KIND_USER, false, 4);
    175 
    176     const char *ebn1[] = { "MV", "P", "TexMatrix", "MVP" };
    177     const Element *ebe1[] = {matrixElem.get(), matrixElem.get(),
    178             matrixElem.get(), matrixElem.get()};
    179     ObjectBaseRef<const Element> constInput = Element::create(rsc, 4, ebe1, ebn1);
    180 
    181     const char *ebn2[] = { "position", "color", "normal", "texture0" };
    182     const Element *ebe2[] = {f4Elem.get(), f4Elem.get(), f3Elem.get(), f2Elem.get()};
    183     ObjectBaseRef<const Element> attrElem = Element::create(rsc, 4, ebe2, ebn2);
    184 
    185     ObjectBaseRef<Type> inputType = Type::getTypeRef(rsc, constInput.get(), 1);
    186 
    187     const char *shaderString =
    188             RS_SHADER_INTERNAL
    189             "varying vec4 varColor;\n"
    190             "varying vec2 varTex0;\n"
    191             "void main() {\n"
    192             "  gl_Position = UNI_MVP * ATTRIB_position;\n"
    193             "  gl_PointSize = 1.0;\n"
    194             "  varColor = ATTRIB_color;\n"
    195             "  varTex0 = ATTRIB_texture0;\n"
    196             "}\n";
    197 
    198     uintptr_t tmp[4];
    199     tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
    200     tmp[1] = (uintptr_t)inputType.get();
    201     tmp[2] = RS_PROGRAM_PARAM_INPUT;
    202     tmp[3] = (uintptr_t)attrElem.get();
    203 
    204     ProgramVertex *pv = new ProgramVertex(rsc, shaderString, strlen(shaderString),
    205                                           nullptr, 0, nullptr, tmp, 4);
    206     Allocation *alloc = Allocation::createAllocation(rsc, inputType.get(),
    207                               RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS);
    208     pv->bindAllocation(rsc, alloc, 0);
    209 
    210     mDefaultAlloc.set(alloc);
    211     mDefault.set(pv);
    212 
    213     updateSize(rsc);
    214 }
    215 
    216 void ProgramVertexState::updateSize(Context *rsc) {
    217     float *f = static_cast<float *>(rsc->mHal.funcs.allocation.lock1D(rsc, mDefaultAlloc.get()));
    218 
    219     float surfaceWidth = (float)rsc->getCurrentSurfaceWidth();
    220     float surfaceHeight = (float)rsc->getCurrentSurfaceHeight();
    221 
    222     Matrix4x4 m;
    223     m.loadOrtho(0, surfaceWidth, surfaceHeight, 0, -1, 1);
    224     memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m));
    225     memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m));
    226 
    227     m.loadIdentity();
    228     memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m.m, sizeof(m));
    229     memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m.m, sizeof(m));
    230     rsc->mHal.funcs.allocation.unlock1D(rsc, mDefaultAlloc.get());
    231 }
    232 
    233 void ProgramVertexState::deinit(Context *rsc) {
    234     mDefaultAlloc.clear();
    235     mDefault.clear();
    236     mLast.clear();
    237 }
    238 
    239 
    240 namespace android {
    241 namespace renderscript {
    242 
    243 RsProgramVertex rsi_ProgramVertexCreate(Context *rsc, const char * shaderText, size_t shaderLength,
    244                                         const char** textureNames, size_t textureNamesCount,
    245                                         const size_t *textureNamesLength,
    246                                         const uintptr_t * params, size_t paramLength) {
    247     ProgramVertex *pv = new ProgramVertex(rsc, shaderText, shaderLength,
    248                                           textureNames, textureNamesCount, textureNamesLength,
    249                                           params, paramLength);
    250     pv->incUserRef();
    251     return pv;
    252 }
    253 
    254 } // namespace renderscript
    255 } // namespace android
    256