2009-05-22 14:03:28 -07:00
|
|
|
/*
|
|
|
|
* 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"
|
|
|
|
|
2009-06-03 16:04:54 -07:00
|
|
|
#include <GLES/gl.h>
|
|
|
|
|
2009-05-22 14:03:28 -07:00
|
|
|
using namespace android;
|
|
|
|
using namespace android::renderscript;
|
|
|
|
|
|
|
|
|
2009-09-25 14:51:22 -07:00
|
|
|
Element::Element(Context *rsc) : ObjectBase(rsc)
|
2009-05-22 14:03:28 -07:00
|
|
|
{
|
2009-12-15 12:58:36 -08:00
|
|
|
mType = RS_TYPE_FLOAT;
|
|
|
|
mIsNormalized = false;
|
|
|
|
mKind = RS_KIND_USER;
|
|
|
|
mBits = 0;
|
2009-09-25 16:37:33 -07:00
|
|
|
mAllocFile = __FILE__;
|
|
|
|
mAllocLine = __LINE__;
|
2009-12-15 12:58:36 -08:00
|
|
|
mFields = NULL;
|
|
|
|
mFieldCount = 0;
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Element::~Element()
|
|
|
|
{
|
|
|
|
clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Element::clear()
|
|
|
|
{
|
2009-12-15 12:58:36 -08:00
|
|
|
delete [] mFields;
|
|
|
|
mFields = NULL;
|
|
|
|
mFieldCount = 0;
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
2009-12-15 12:58:36 -08:00
|
|
|
/*
|
2009-05-22 14:03:28 -07:00
|
|
|
void Element::setComponent(uint32_t idx, Component *c)
|
|
|
|
{
|
|
|
|
rsAssert(!mComponents[idx].get());
|
|
|
|
rsAssert(idx < mComponentCount);
|
|
|
|
mComponents[idx].set(c);
|
2009-09-27 17:50:38 -07:00
|
|
|
|
|
|
|
// Fixme: This should probably not be here
|
2009-08-27 20:23:34 -07:00
|
|
|
c->incUserRef();
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
2009-12-15 12:58:36 -08:00
|
|
|
*/
|
2009-05-22 14:03:28 -07:00
|
|
|
|
|
|
|
size_t Element::getSizeBits() const
|
|
|
|
{
|
2009-12-15 12:58:36 -08:00
|
|
|
if (!mFieldCount) {
|
|
|
|
return mBits;
|
|
|
|
}
|
|
|
|
|
2009-05-22 14:03:28 -07:00
|
|
|
size_t total = 0;
|
2009-12-15 12:58:36 -08:00
|
|
|
for (size_t ct=0; ct < mFieldCount; ct++) {
|
|
|
|
total += mFields[ct].e->mBits;
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
|
|
|
return total;
|
|
|
|
}
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
size_t Element::getFieldOffsetBits(uint32_t componentNumber) const
|
2009-05-22 14:03:28 -07:00
|
|
|
{
|
|
|
|
size_t offset = 0;
|
|
|
|
for (uint32_t ct = 0; ct < componentNumber; ct++) {
|
2009-12-15 12:58:36 -08:00
|
|
|
offset += mFields[ct].e->mBits;
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
|
|
|
return offset;
|
|
|
|
}
|
|
|
|
|
2009-06-03 16:04:54 -07:00
|
|
|
uint32_t Element::getGLType() const
|
|
|
|
{
|
|
|
|
int bits[4];
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
if (!mFieldCount) {
|
|
|
|
switch (mType) {
|
|
|
|
case RS_TYPE_FLOAT:
|
|
|
|
if (mBits == 32) {
|
|
|
|
return GL_FLOAT;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
case RS_TYPE_SIGNED:
|
|
|
|
switch (mBits) {
|
|
|
|
case 8:
|
|
|
|
return GL_BYTE;
|
|
|
|
case 16:
|
|
|
|
return GL_SHORT;
|
|
|
|
//case 32:
|
|
|
|
//return GL_INT;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
case RS_TYPE_UNSIGNED:
|
|
|
|
switch (mBits) {
|
|
|
|
case 8:
|
|
|
|
return GL_UNSIGNED_BYTE;
|
|
|
|
case 16:
|
|
|
|
return GL_UNSIGNED_SHORT;
|
|
|
|
//case 32:
|
|
|
|
//return GL_UNSIGNED_INT;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mFieldCount > 4) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
for (uint32_t ct=0; ct < mFieldCount; ct++) {
|
|
|
|
bits[ct] = mFields[ct].e->mBits;
|
|
|
|
if (mFields[ct].e->mFieldCount) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (mFields[ct].e->mType != RS_TYPE_UNSIGNED) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return 0;
|
|
|
|
}
|
2009-12-15 12:58:36 -08:00
|
|
|
if (!mFields[ct].e->mIsNormalized) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
switch(mFieldCount) {
|
2009-06-03 16:04:54 -07:00
|
|
|
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
|
|
|
|
{
|
2009-12-15 12:58:36 -08:00
|
|
|
if (!mFieldCount) {
|
|
|
|
if (mKind == RS_KIND_ALPHA) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return GL_ALPHA;
|
|
|
|
}
|
2009-12-15 12:58:36 -08:00
|
|
|
if (mKind == RS_KIND_LUMINANCE) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return GL_LUMINANCE;
|
|
|
|
}
|
2009-12-15 12:58:36 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
switch(mFieldCount) {
|
2009-06-03 16:04:54 -07:00
|
|
|
case 2:
|
2009-12-15 12:58:36 -08:00
|
|
|
if ((mFields[0].e->mKind == RS_KIND_LUMINANCE) &&
|
|
|
|
(mFields[1].e->mKind == RS_KIND_ALPHA)) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return GL_LUMINANCE_ALPHA;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
2009-12-15 12:58:36 -08:00
|
|
|
if ((mFields[0].e->mKind == RS_KIND_RED) &&
|
|
|
|
(mFields[1].e->mKind == RS_KIND_GREEN) &&
|
|
|
|
(mFields[2].e->mKind == RS_KIND_BLUE)) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return GL_RGB;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 4:
|
2009-12-15 12:58:36 -08:00
|
|
|
if ((mFields[0].e->mKind == RS_KIND_RED) &&
|
|
|
|
(mFields[1].e->mKind == RS_KIND_GREEN) &&
|
|
|
|
(mFields[2].e->mKind == RS_KIND_BLUE) &&
|
|
|
|
(mFields[3].e->mKind == RS_KIND_ALPHA)) {
|
2009-06-03 16:04:54 -07:00
|
|
|
return GL_RGBA;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
const char * Element::getCType() const
|
|
|
|
{
|
|
|
|
switch(mType) {
|
|
|
|
case RS_TYPE_FLOAT:
|
|
|
|
return "float";
|
|
|
|
case RS_TYPE_SIGNED:
|
|
|
|
case RS_TYPE_UNSIGNED:
|
|
|
|
switch(mBits) {
|
|
|
|
case 32:
|
|
|
|
return "int";
|
|
|
|
case 16:
|
|
|
|
return "short";
|
|
|
|
case 8:
|
|
|
|
return "char";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-06-03 16:04:54 -07:00
|
|
|
|
2009-09-27 17:50:38 -07:00
|
|
|
void Element::dumpLOGV(const char *prefix) const
|
|
|
|
{
|
|
|
|
ObjectBase::dumpLOGV(prefix);
|
2009-12-15 12:58:36 -08:00
|
|
|
LOGV("%s Element: components %i, size %i", prefix, mFieldCount, mBits);
|
|
|
|
for (uint32_t ct = 0; ct < mFieldCount; ct++) {
|
2009-09-27 17:50:38 -07:00
|
|
|
char buf[1024];
|
|
|
|
sprintf(buf, "%s component %i: ", prefix, ct);
|
2009-12-15 12:58:36 -08:00
|
|
|
//mComponents[ct]->dumpLOGV(buf);
|
2009-09-27 17:50:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
Element * Element::create(Context *rsc, RsDataKind dk, RsDataType dt,
|
|
|
|
bool isNorm, size_t bits)
|
|
|
|
{
|
|
|
|
Element *e = new Element(rsc);
|
|
|
|
e->mKind = dk;
|
|
|
|
e->mType = dt;
|
|
|
|
e->mIsNormalized = isNorm;
|
|
|
|
e->mBits = bits;
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
Element * Element::create(Context *rsc, Element **ein, const char **nin,
|
|
|
|
const size_t * lengths, size_t count)
|
|
|
|
{
|
|
|
|
Element *e = new Element(rsc);
|
|
|
|
e->mFields = new ElementField_t [count];
|
|
|
|
e->mFieldCount = count;
|
|
|
|
|
|
|
|
for (size_t ct=0; ct < count; ct++) {
|
|
|
|
e->mFields[ct].e.set(ein[ct]);
|
|
|
|
e->mFields[ct].name.setTo(nin[ct], lengths[ct]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return e;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-05-22 14:03:28 -07:00
|
|
|
ElementState::ElementState()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
ElementState::~ElementState()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
|
2009-05-22 14:03:28 -07:00
|
|
|
/////////////////////////////////////////
|
2009-08-09 17:01:55 -07:00
|
|
|
//
|
2009-05-22 14:03:28 -07:00
|
|
|
|
|
|
|
namespace android {
|
|
|
|
namespace renderscript {
|
|
|
|
|
|
|
|
void rsi_ElementBegin(Context *rsc)
|
|
|
|
{
|
2009-12-15 12:58:36 -08:00
|
|
|
ElementState * sec = &rsc->mStateElement;
|
|
|
|
|
|
|
|
sec->mBuildList.clear();
|
|
|
|
sec->mNames.clear();
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
|
|
|
|
2009-08-12 17:54:11 -07:00
|
|
|
void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name)
|
2009-05-22 14:03:28 -07:00
|
|
|
{
|
|
|
|
ElementState * sec = &rsc->mStateElement;
|
2009-09-27 17:50:38 -07:00
|
|
|
|
|
|
|
rsAssert(bits > 0);
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
Element *c = Element::create(rsc, dk, dt, isNormalized, bits);
|
|
|
|
sec->mBuildList.add(c);
|
|
|
|
if (name)
|
|
|
|
sec->mNames.add(String8(name));
|
|
|
|
else
|
|
|
|
sec->mNames.add(String8(""));
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
RsElement rsi_ElementCreate(Context *rsc)
|
|
|
|
{
|
|
|
|
ElementState * sec = &rsc->mStateElement;
|
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
size_t count = sec->mBuildList.size();
|
|
|
|
rsAssert(count > 0);
|
|
|
|
|
|
|
|
if (count == 1) {
|
|
|
|
Element *se = sec->mBuildList[0];
|
|
|
|
se->incUserRef();
|
|
|
|
sec->mBuildList.clear();
|
|
|
|
sec->mNames.clear();
|
|
|
|
return se;
|
|
|
|
}
|
|
|
|
|
|
|
|
Element ** tmpElements = (Element **)calloc(count, sizeof(Element *));
|
|
|
|
const char ** tmpNames = (const char **)calloc(count, sizeof(char *));
|
|
|
|
size_t * tmpLengths = (size_t *)calloc(count, sizeof(size_t));
|
|
|
|
|
2009-09-27 17:50:38 -07:00
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
for (size_t ct = 0; ct < count; ct++) {
|
|
|
|
tmpElements[ct] = sec->mBuildList[ct];
|
|
|
|
tmpNames[ct] = sec->mNames[ct].string();
|
|
|
|
tmpLengths[ct] = sec->mNames[ct].length();
|
2009-05-22 14:03:28 -07:00
|
|
|
}
|
2009-12-15 12:58:36 -08:00
|
|
|
Element *se = Element::create(rsc, tmpElements, tmpNames, tmpLengths, count);
|
2009-05-22 14:03:28 -07:00
|
|
|
|
2009-12-15 12:58:36 -08:00
|
|
|
sec->mBuildList.clear();
|
|
|
|
sec->mNames.clear();
|
2009-08-27 20:23:34 -07:00
|
|
|
se->incUserRef();
|
2009-12-15 12:58:36 -08:00
|
|
|
free(tmpElements);
|
|
|
|
free(tmpNames);
|
|
|
|
free(tmpLengths);
|
2009-05-22 14:03:28 -07:00
|
|
|
return se;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|