diff options
author | Alex Sakhartchouk <alexst@google.com> | 2011-04-29 16:49:08 -0700 |
---|---|---|
committer | Alex Sakhartchouk <alexst@google.com> | 2011-04-29 16:49:08 -0700 |
commit | 4a36b45c72b91045db49c54d33fd7a05fc5a7a3d (patch) | |
tree | 15ae5ac6f9ad21b859de875785ff551389bf65c5 /libs/rs/rsProgram.cpp | |
parent | b4a56f10d875dc62a9c73008f98596c7e32fc249 (diff) |
Moving renderscript GL code into the HAL
This change affects
- shaders
- meshes
- fonts
- quad rendering
Change-Id: I2a53acb4cd1fa8f4c6e67668f6ee969f3d7f7aa1
Diffstat (limited to 'libs/rs/rsProgram.cpp')
-rw-r--r-- | libs/rs/rsProgram.cpp | 420 |
1 files changed, 50 insertions, 370 deletions
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 4ef05bf4372f..28fa0617b99d 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 The Android Open Source Project + * Copyright (C) 2011 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. @@ -15,11 +15,6 @@ */ #include "rsContext.h" -#ifndef ANDROID_RS_SERIALIZE -#include <GLES2/gl2.h> -#include <GLES2/gl2ext.h> -#endif //ANDROID_RS_SERIALIZE - #include "rsProgram.h" using namespace android; @@ -36,26 +31,22 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, initMemberVars(); for (uint32_t ct=0; ct < paramLength; ct+=2) { if (params[ct] == RS_PROGRAM_PARAM_INPUT) { - mInputCount++; - } - if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) { - mOutputCount++; + mHal.state.inputElementsCount++; } if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { - mConstantCount++; + mHal.state.constantsCount++; } if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) { - mTextureCount++; + mHal.state.texturesCount++; } } - mTextures = new ObjectBaseRef<Allocation>[mTextureCount]; - mSamplers = new ObjectBaseRef<Sampler>[mTextureCount]; - mTextureTargets = new RsTextureTarget[mTextureCount]; - mInputElements = new ObjectBaseRef<Element>[mInputCount]; - mOutputElements = new ObjectBaseRef<Element>[mOutputCount]; - mConstantTypes = new ObjectBaseRef<Type>[mConstantCount]; - mConstants = new ObjectBaseRef<Allocation>[mConstantCount]; + mHal.state.textures = new ObjectBaseRef<Allocation>[mHal.state.texturesCount]; + mHal.state.samplers = new ObjectBaseRef<Sampler>[mHal.state.texturesCount]; + mHal.state.textureTargets = new RsTextureTarget[mHal.state.texturesCount]; + mHal.state.inputElements = new ObjectBaseRef<Element>[mHal.state.inputElementsCount]; + mHal.state.constantTypes = new ObjectBaseRef<Type>[mHal.state.constantsCount]; + mHal.state.constants = new ObjectBaseRef<Allocation>[mHal.state.constantsCount]; uint32_t input = 0; uint32_t output = 0; @@ -63,16 +54,13 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, uint32_t texture = 0; for (uint32_t ct=0; ct < paramLength; ct+=2) { if (params[ct] == RS_PROGRAM_PARAM_INPUT) { - mInputElements[input++].set(reinterpret_cast<Element *>(params[ct+1])); - } - if (params[ct] == RS_PROGRAM_PARAM_OUTPUT) { - mOutputElements[output++].set(reinterpret_cast<Element *>(params[ct+1])); + mHal.state.inputElements[input++].set(reinterpret_cast<Element *>(params[ct+1])); } if (params[ct] == RS_PROGRAM_PARAM_CONSTANT) { - mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1])); + mHal.state.constantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1])); } if (params[ct] == RS_PROGRAM_PARAM_TEXTURE_TYPE) { - mTextureTargets[texture++] = (RsTextureTarget)params[ct+1]; + mHal.state.textureTargets[texture++] = (RsTextureTarget)params[ct+1]; } } mIsInternal = false; @@ -84,88 +72,69 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, shaderLength -= internalTokenLen; } mUserShader.setTo(shaderText, shaderLength); - - initAttribAndUniformArray(); } Program::~Program() { - if (mRSC->props.mLogShaders) { - LOGV("Program::~Program with shader id %u", mShaderID); - } - if (mShaderID) { - glDeleteShader(mShaderID); - } - - for (uint32_t ct=0; ct < mConstantCount; ct++) { + for (uint32_t ct=0; ct < mHal.state.constantsCount; ct++) { bindAllocation(NULL, NULL, ct); } - for (uint32_t ct=0; ct < mTextureCount; ct++) { + for (uint32_t ct=0; ct < mHal.state.texturesCount; ct++) { bindTexture(NULL, ct, NULL); bindSampler(NULL, ct, NULL); } - delete[] mTextures; - delete[] mSamplers; - delete[] mTextureTargets; - delete[] mInputElements; - delete[] mOutputElements; - delete[] mConstantTypes; - delete[] mConstants; - delete[] mAttribNames; - delete[] mUniformNames; - delete[] mUniformArraySizes; - mInputCount = 0; - mOutputCount = 0; - mConstantCount = 0; + delete[] mHal.state.textures; + delete[] mHal.state.samplers; + delete[] mHal.state.textureTargets; + delete[] mHal.state.inputElements; + delete[] mHal.state.constantTypes; + delete[] mHal.state.constants; + mHal.state.inputElementsCount = 0; + mHal.state.constantsCount = 0; + mHal.state.texturesCount = 0; } void Program::initMemberVars() { mDirty = true; - mShaderID = 0; - mAttribCount = 0; - mUniformCount = 0; - mTextureCount = 0; - mTextures = NULL; - mSamplers = NULL; - mTextureTargets = NULL; - mInputElements = NULL; - mOutputElements = NULL; - mConstantTypes = NULL; - mConstants = NULL; - mAttribNames = NULL; - mUniformNames = NULL; - mUniformArraySizes = NULL; - mInputCount = 0; - mOutputCount = 0; - mConstantCount = 0; - mIsValid = false; + mHal.drv = NULL; + mHal.state.textures = NULL; + mHal.state.samplers = NULL; + mHal.state.textureTargets = NULL; + mHal.state.inputElements = NULL; + mHal.state.constantTypes = NULL; + mHal.state.constants = NULL; + + mHal.state.inputElementsCount = 0; + mHal.state.constantsCount = 0; + mHal.state.texturesCount = 0; + mIsInternal = false; } void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) { if (alloc != NULL) { - if (slot >= mConstantCount) { + if (slot >= mHal.state.constantsCount) { LOGE("Attempt to bind alloc at slot %u, on shader id %u, but const count is %u", - slot, (uint32_t)this, mConstantCount); + slot, (uint32_t)this, mHal.state.constantsCount); rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation"); return; } - if (!alloc->getType()->isEqual(mConstantTypes[slot].get())) { + if (!alloc->getType()->isEqual(mHal.state.constantTypes[slot].get())) { LOGE("Attempt to bind alloc at slot %u, on shader id %u, but types mismatch", slot, (uint32_t)this); rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind allocation"); return; } } - if (mConstants[slot].get() == alloc) { + if (mHal.state.constants[slot].get() == alloc) { return; } - if (mConstants[slot].get()) { - mConstants[slot].get()->removeProgramToDirty(this); + if (mHal.state.constants[slot].get()) { + mHal.state.constants[slot].get()->removeProgramToDirty(this); } - mConstants[slot].set(alloc); + mHal.state.constants[slot].set(alloc); if (alloc) { alloc->addProgramToDirty(this); } @@ -173,327 +142,38 @@ void Program::bindAllocation(Context *rsc, Allocation *alloc, uint32_t slot) { } void Program::bindTexture(Context *rsc, uint32_t slot, Allocation *a) { - if (slot >= mTextureCount) { - LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mTextureCount); + if (slot >= mHal.state.texturesCount) { + LOGE("Attempt to bind texture to slot %u but tex count is %u", slot, mHal.state.texturesCount); rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind texture"); return; } - if (a && a->getType()->getDimFaces() && mTextureTargets[slot] != RS_TEXTURE_CUBE) { + if (a && a->getType()->getDimFaces() && mHal.state.textureTargets[slot] != RS_TEXTURE_CUBE) { LOGE("Attempt to bind cubemap to slot %u but 2d texture needed", slot); rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind cubemap to 2d texture slot"); return; } //LOGE("bindtex %i %p", slot, a); - mTextures[slot].set(a); + mHal.state.textures[slot].set(a); mDirty = true; } void Program::bindSampler(Context *rsc, uint32_t slot, Sampler *s) { - if (slot >= mTextureCount) { - LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mTextureCount); + if (slot >= mHal.state.texturesCount) { + LOGE("Attempt to bind sampler to slot %u but tex count is %u", slot, mHal.state.texturesCount); rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind sampler"); return; } - mSamplers[slot].set(s); + mHal.state.samplers[slot].set(s); mDirty = true; } -String8 Program::getGLSLInputString() const { - String8 s; - for (uint32_t ct=0; ct < mInputCount; ct++) { - const Element *e = mInputElements[ct].get(); - for (uint32_t field=0; field < e->getFieldCount(); field++) { - const Element *f = e->getField(field); - - // Cannot be complex - rsAssert(!f->getFieldCount()); - switch (f->getComponent().getVectorSize()) { - case 1: s.append("attribute float ATTRIB_"); break; - case 2: s.append("attribute vec2 ATTRIB_"); break; - case 3: s.append("attribute vec3 ATTRIB_"); break; - case 4: s.append("attribute vec4 ATTRIB_"); break; - default: - rsAssert(0); - } - - s.append(e->getFieldName(field)); - s.append(";\n"); - } - } - return s; -} - -String8 Program::getGLSLOutputString() const { - return String8(); -} - -String8 Program::getGLSLConstantString() const { - return String8(); -} - -void Program::createShader() { -} - -bool Program::loadShader(Context *rsc, uint32_t type) { - mShaderID = glCreateShader(type); - rsAssert(mShaderID); - - if (rsc->props.mLogShaders) { - LOGV("Loading shader type %x, ID %i", type, mShaderID); - LOGV("%s", mShader.string()); - } - - if (mShaderID) { - const char * ss = mShader.string(); - glShaderSource(mShaderID, 1, &ss, NULL); - glCompileShader(mShaderID); - - GLint compiled = 0; - glGetShaderiv(mShaderID, GL_COMPILE_STATUS, &compiled); - if (!compiled) { - GLint infoLen = 0; - glGetShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLen); - if (infoLen) { - char* buf = (char*) malloc(infoLen); - if (buf) { - glGetShaderInfoLog(mShaderID, infoLen, NULL, buf); - LOGE("Could not compile shader \n%s\n", buf); - free(buf); - } - glDeleteShader(mShaderID); - mShaderID = 0; - rsc->setError(RS_ERROR_BAD_SHADER, "Error returned from GL driver loading shader text,"); - return false; - } - } - } - - if (rsc->props.mLogShaders) { - LOGV("--Shader load result %x ", glGetError()); - } - mIsValid = true; - return true; -} - void Program::setShader(const char *txt, uint32_t len) { mUserShader.setTo(txt, len); } -void Program::appendUserConstants() { - for (uint32_t ct=0; ct < mConstantCount; ct++) { - const Element *e = mConstantTypes[ct]->getElement(); - for (uint32_t field=0; field < e->getFieldCount(); field++) { - const Element *f = e->getField(field); - const char *fn = e->getFieldName(field); - - if (fn[0] == '#') { - continue; - } - - // Cannot be complex - rsAssert(!f->getFieldCount()); - if (f->getType() == RS_TYPE_MATRIX_4X4) { - mShader.append("uniform mat4 UNI_"); - } else if (f->getType() == RS_TYPE_MATRIX_3X3) { - mShader.append("uniform mat3 UNI_"); - } else if (f->getType() == RS_TYPE_MATRIX_2X2) { - mShader.append("uniform mat2 UNI_"); - } else { - switch (f->getComponent().getVectorSize()) { - case 1: mShader.append("uniform float UNI_"); break; - case 2: mShader.append("uniform vec2 UNI_"); break; - case 3: mShader.append("uniform vec3 UNI_"); break; - case 4: mShader.append("uniform vec4 UNI_"); break; - default: - rsAssert(0); - } - } - - mShader.append(fn); - if (e->getFieldArraySize(field) > 1) { - mShader.appendFormat("[%d]", e->getFieldArraySize(field)); - } - mShader.append(";\n"); - } - } -} - -void Program::logUniform(const Element *field, const float *fd, uint32_t arraySize ) { - RsDataType dataType = field->getType(); - uint32_t elementSize = field->getSizeBytes() / sizeof(float); - for (uint32_t i = 0; i < arraySize; i ++) { - if (arraySize > 1) { - LOGV("Array Element [%u]", i); - } - if (dataType == RS_TYPE_MATRIX_4X4) { - LOGV("Matrix4x4"); - LOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]); - LOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]); - LOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]); - LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]); - } else if (dataType == RS_TYPE_MATRIX_3X3) { - LOGV("Matrix3x3"); - LOGV("{%f, %f, %f", fd[0], fd[3], fd[6]); - LOGV(" %f, %f, %f", fd[1], fd[4], fd[7]); - LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]); - } else if (dataType == RS_TYPE_MATRIX_2X2) { - LOGV("Matrix2x2"); - LOGV("{%f, %f", fd[0], fd[2]); - LOGV(" %f, %f}", fd[1], fd[3]); - } else { - switch (field->getComponent().getVectorSize()) { - case 1: - LOGV("Uniform 1 = %f", fd[0]); - break; - case 2: - LOGV("Uniform 2 = %f %f", fd[0], fd[1]); - break; - case 3: - LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]); - break; - case 4: - LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]); - break; - default: - rsAssert(0); - } - } - LOGE("Element size %u data=%p", elementSize, fd); - fd += elementSize; - LOGE("New data=%p", fd); - } -} - -void Program::setUniform(Context *rsc, const Element *field, const float *fd, - int32_t slot, uint32_t arraySize ) { - RsDataType dataType = field->getType(); - if (dataType == RS_TYPE_MATRIX_4X4) { - glUniformMatrix4fv(slot, arraySize, GL_FALSE, fd); - } else if (dataType == RS_TYPE_MATRIX_3X3) { - glUniformMatrix3fv(slot, arraySize, GL_FALSE, fd); - } else if (dataType == RS_TYPE_MATRIX_2X2) { - glUniformMatrix2fv(slot, arraySize, GL_FALSE, fd); - } else { - switch (field->getComponent().getVectorSize()) { - case 1: - glUniform1fv(slot, arraySize, fd); - break; - case 2: - glUniform2fv(slot, arraySize, fd); - break; - case 3: - glUniform3fv(slot, arraySize, fd); - break; - case 4: - glUniform4fv(slot, arraySize, fd); - break; - default: - rsAssert(0); - } - } -} - -void Program::setupUserConstants(Context *rsc, ShaderCache *sc, bool isFragment) { - uint32_t uidx = 0; - for (uint32_t ct=0; ct < mConstantCount; ct++) { - Allocation *alloc = mConstants[ct].get(); - if (!alloc) { - LOGE("Attempting to set constants on shader id %u, but alloc at slot %u is not set", (uint32_t)this, ct); - rsc->setError(RS_ERROR_BAD_SHADER, "No constant allocation bound"); - continue; - } - - const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr()); - const Element *e = mConstantTypes[ct]->getElement(); - for (uint32_t field=0; field < e->getFieldCount(); field++) { - const Element *f = e->getField(field); - const char *fieldName = e->getFieldName(field); - // If this field is padding, skip it - if (fieldName[0] == '#') { - continue; - } - - uint32_t offset = e->getFieldOffsetBytes(field); - const float *fd = reinterpret_cast<const float *>(&data[offset]); - - int32_t slot = -1; - uint32_t arraySize = 1; - if (!isFragment) { - slot = sc->vtxUniformSlot(uidx); - arraySize = sc->vtxUniformSize(uidx); - } else { - slot = sc->fragUniformSlot(uidx); - arraySize = sc->fragUniformSize(uidx); - } - if (rsc->props.mLogShadersUniforms) { - LOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s", slot, offset, ct, field, uidx, fieldName); - } - uidx ++; - if (slot < 0) { - continue; - } - - if (rsc->props.mLogShadersUniforms) { - logUniform(f, fd, arraySize); - } - setUniform(rsc, f, fd, slot, arraySize); - } - } -} - -void Program::initAttribAndUniformArray() { - mAttribCount = 0; - for (uint32_t ct=0; ct < mInputCount; ct++) { - const Element *elem = mInputElements[ct].get(); - for (uint32_t field=0; field < elem->getFieldCount(); field++) { - if (elem->getFieldName(field)[0] != '#') { - mAttribCount ++; - } - } - } - - mUniformCount = 0; - for (uint32_t ct=0; ct < mConstantCount; ct++) { - const Element *elem = mConstantTypes[ct]->getElement(); - - for (uint32_t field=0; field < elem->getFieldCount(); field++) { - if (elem->getFieldName(field)[0] != '#') { - mUniformCount ++; - } - } - } - mUniformCount += mTextureCount; - - if (mAttribCount) { - mAttribNames = new String8[mAttribCount]; - } - if (mUniformCount) { - mUniformNames = new String8[mUniformCount]; - mUniformArraySizes = new uint32_t[mUniformCount]; - } -} - -void Program::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths, uint32_t *count, const char *prefix) { - rsAssert(e->getFieldCount()); - for (uint32_t ct=0; ct < e->getFieldCount(); ct++) { - const Element *ce = e->getField(ct); - if (ce->getFieldCount()) { - initAddUserElement(ce, names, arrayLengths, count, prefix); - } else if (e->getFieldName(ct)[0] != '#') { - String8 tmp(prefix); - tmp.append(e->getFieldName(ct)); - names[*count].setTo(tmp.string()); - if (arrayLengths) { - arrayLengths[*count] = e->getFieldArraySize(ct); - } - (*count)++; - } - } -} - namespace android { namespace renderscript { |