/* * Copyright (C) 2009 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "rsContext.h" #include <GLES/gl.h> using namespace android; using namespace android::renderscript; Element::Element(Context *rsc) : ObjectBase(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; mComponents = NULL; mComponentCount = 0; } Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc) { mAllocFile = __FILE__; mAllocLine = __LINE__; mComponents = new ObjectBaseRef<Component> [count]; mComponentCount = count; } Element::~Element() { clear(); } void Element::clear() { delete [] mComponents; mComponents = NULL; mComponentCount = 0; } void Element::setComponent(uint32_t idx, Component *c) { rsAssert(!mComponents[idx].get()); rsAssert(idx < mComponentCount); mComponents[idx].set(c); // Fixme: This should probably not be here c->incUserRef(); } size_t Element::getSizeBits() const { size_t total = 0; for (size_t ct=0; ct < mComponentCount; ct++) { total += mComponents[ct]->getBits(); } return total; } size_t Element::getComponentOffsetBits(uint32_t componentNumber) const { size_t offset = 0; for (uint32_t ct = 0; ct < componentNumber; ct++) { offset += mComponents[ct]->getBits(); } return offset; } uint32_t Element::getGLType() const { int bits[4]; if (mComponentCount > 4) { return 0; } for (uint32_t ct=0; ct < mComponentCount; ct++) { bits[ct] = mComponents[ct]->getBits(); if (mComponents[ct]->getType() != Component::UNSIGNED) { return 0; } if (!mComponents[ct]->getIsNormalized()) { return 0; } } switch(mComponentCount) { case 1: if (bits[0] == 8) { return GL_UNSIGNED_BYTE; } return 0; case 2: if ((bits[0] == 8) && (bits[1] == 8)) { return GL_UNSIGNED_BYTE; } return 0; case 3: if ((bits[0] == 8) && (bits[1] == 8) && (bits[2] == 8)) { return GL_UNSIGNED_BYTE; } if ((bits[0] == 5) && (bits[1] == 6) && (bits[2] == 5)) { return GL_UNSIGNED_SHORT_5_6_5; } return 0; case 4: if ((bits[0] == 8) && (bits[1] == 8) && (bits[2] == 8) && (bits[3] == 8)) { return GL_UNSIGNED_BYTE; } if ((bits[0] == 4) && (bits[1] == 4) && (bits[2] == 4) && (bits[3] == 4)) { return GL_UNSIGNED_SHORT_4_4_4_4; } if ((bits[0] == 5) && (bits[1] == 5) && (bits[2] == 5) && (bits[3] == 1)) { return GL_UNSIGNED_SHORT_5_5_5_1; } } return 0; } uint32_t Element::getGLFormat() const { switch(mComponentCount) { case 1: if (mComponents[0]->getKind() == Component::ALPHA) { return GL_ALPHA; } if (mComponents[0]->getKind() == Component::LUMINANCE) { return GL_LUMINANCE; } break; case 2: if ((mComponents[0]->getKind() == Component::LUMINANCE) && (mComponents[1]->getKind() == Component::ALPHA)) { return GL_LUMINANCE_ALPHA; } break; case 3: if ((mComponents[0]->getKind() == Component::RED) && (mComponents[1]->getKind() == Component::GREEN) && (mComponents[2]->getKind() == Component::BLUE)) { return GL_RGB; } break; case 4: if ((mComponents[0]->getKind() == Component::RED) && (mComponents[1]->getKind() == Component::GREEN) && (mComponents[2]->getKind() == Component::BLUE) && (mComponents[3]->getKind() == Component::ALPHA)) { return GL_RGBA; } break; } return 0; } void Element::dumpLOGV(const char *prefix) const { ObjectBase::dumpLOGV(prefix); LOGV("%s Element: components %i, size %i", prefix, mComponentCount, getSizeBytes()); for (uint32_t ct = 0; ct < mComponentCount; ct++) { char buf[1024]; sprintf(buf, "%s component %i: ", prefix, ct); mComponents[ct]->dumpLOGV(buf); } } ElementState::ElementState() { } ElementState::~ElementState() { } ///////////////////////////////////////// // namespace android { namespace renderscript { void rsi_ElementBegin(Context *rsc) { rsc->mStateElement.mComponentBuildList.clear(); } void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name) { ElementState * sec = &rsc->mStateElement; rsAssert(bits > 0); Component *c = new Component(rsc, static_cast<Component::DataKind>(dk), static_cast<Component::DataType>(dt), isNormalized, bits, name); sec->mComponentBuildList.add(c); } RsElement rsi_ElementCreate(Context *rsc) { ElementState * sec = &rsc->mStateElement; Element *se = new Element(rsc, sec->mComponentBuildList.size()); rsAssert(se->getComponentCount() > 0); for (size_t ct = 0; ct < se->getComponentCount(); ct++) { se->setComponent(ct, sec->mComponentBuildList[ct]); } rsc->mStateElement.mComponentBuildList.clear(); se->incUserRef(); return se; } } }