1 /*
2 * Copyright (C) 2009 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
19 #include <GLES/gl.h>
20
21 using namespace android;
22 using namespace android::renderscript;
23
24
Element(Context * rsc)25 Element::Element(Context *rsc) : ObjectBase(rsc)
26 {
27 mAllocFile = __FILE__;
28 mAllocLine = __LINE__;
29 mComponents = NULL;
30 mComponentCount = 0;
31 }
32
Element(Context * rsc,uint32_t count)33 Element::Element(Context *rsc, uint32_t count) : ObjectBase(rsc)
34 {
35 mAllocFile = __FILE__;
36 mAllocLine = __LINE__;
37 mComponents = new ObjectBaseRef<Component> [count];
38 mComponentCount = count;
39 }
40
~Element()41 Element::~Element()
42 {
43 clear();
44 }
45
clear()46 void Element::clear()
47 {
48 delete [] mComponents;
49 mComponents = NULL;
50 mComponentCount = 0;
51 }
52
setComponent(uint32_t idx,Component * c)53 void Element::setComponent(uint32_t idx, Component *c)
54 {
55 rsAssert(!mComponents[idx].get());
56 rsAssert(idx < mComponentCount);
57 mComponents[idx].set(c);
58
59 // Fixme: This should probably not be here
60 c->incUserRef();
61 }
62
63
getSizeBits() const64 size_t Element::getSizeBits() const
65 {
66 size_t total = 0;
67 for (size_t ct=0; ct < mComponentCount; ct++) {
68 total += mComponents[ct]->getBits();
69 }
70 return total;
71 }
72
getComponentOffsetBits(uint32_t componentNumber) const73 size_t Element::getComponentOffsetBits(uint32_t componentNumber) const
74 {
75 size_t offset = 0;
76 for (uint32_t ct = 0; ct < componentNumber; ct++) {
77 offset += mComponents[ct]->getBits();
78 }
79 return offset;
80 }
81
getGLType() const82 uint32_t Element::getGLType() const
83 {
84 int bits[4];
85
86 if (mComponentCount > 4) {
87 return 0;
88 }
89
90 for (uint32_t ct=0; ct < mComponentCount; ct++) {
91 bits[ct] = mComponents[ct]->getBits();
92 if (mComponents[ct]->getType() != Component::UNSIGNED) {
93 return 0;
94 }
95 if (!mComponents[ct]->getIsNormalized()) {
96 return 0;
97 }
98 }
99
100 switch(mComponentCount) {
101 case 1:
102 if (bits[0] == 8) {
103 return GL_UNSIGNED_BYTE;
104 }
105 return 0;
106 case 2:
107 if ((bits[0] == 8) &&
108 (bits[1] == 8)) {
109 return GL_UNSIGNED_BYTE;
110 }
111 return 0;
112 case 3:
113 if ((bits[0] == 8) &&
114 (bits[1] == 8) &&
115 (bits[2] == 8)) {
116 return GL_UNSIGNED_BYTE;
117 }
118 if ((bits[0] == 5) &&
119 (bits[1] == 6) &&
120 (bits[2] == 5)) {
121 return GL_UNSIGNED_SHORT_5_6_5;
122 }
123 return 0;
124 case 4:
125 if ((bits[0] == 8) &&
126 (bits[1] == 8) &&
127 (bits[2] == 8) &&
128 (bits[3] == 8)) {
129 return GL_UNSIGNED_BYTE;
130 }
131 if ((bits[0] == 4) &&
132 (bits[1] == 4) &&
133 (bits[2] == 4) &&
134 (bits[3] == 4)) {
135 return GL_UNSIGNED_SHORT_4_4_4_4;
136 }
137 if ((bits[0] == 5) &&
138 (bits[1] == 5) &&
139 (bits[2] == 5) &&
140 (bits[3] == 1)) {
141 return GL_UNSIGNED_SHORT_5_5_5_1;
142 }
143 }
144 return 0;
145 }
146
getGLFormat() const147 uint32_t Element::getGLFormat() const
148 {
149 switch(mComponentCount) {
150 case 1:
151 if (mComponents[0]->getKind() == Component::ALPHA) {
152 return GL_ALPHA;
153 }
154 if (mComponents[0]->getKind() == Component::LUMINANCE) {
155 return GL_LUMINANCE;
156 }
157 break;
158 case 2:
159 if ((mComponents[0]->getKind() == Component::LUMINANCE) &&
160 (mComponents[1]->getKind() == Component::ALPHA)) {
161 return GL_LUMINANCE_ALPHA;
162 }
163 break;
164 case 3:
165 if ((mComponents[0]->getKind() == Component::RED) &&
166 (mComponents[1]->getKind() == Component::GREEN) &&
167 (mComponents[2]->getKind() == Component::BLUE)) {
168 return GL_RGB;
169 }
170 break;
171 case 4:
172 if ((mComponents[0]->getKind() == Component::RED) &&
173 (mComponents[1]->getKind() == Component::GREEN) &&
174 (mComponents[2]->getKind() == Component::BLUE) &&
175 (mComponents[3]->getKind() == Component::ALPHA)) {
176 return GL_RGBA;
177 }
178 break;
179 }
180 return 0;
181 }
182
183
dumpLOGV(const char * prefix) const184 void Element::dumpLOGV(const char *prefix) const
185 {
186 ObjectBase::dumpLOGV(prefix);
187 LOGV("%s Element: components %i, size %i", prefix, mComponentCount, getSizeBytes());
188 for (uint32_t ct = 0; ct < mComponentCount; ct++) {
189 char buf[1024];
190 sprintf(buf, "%s component %i: ", prefix, ct);
191 mComponents[ct]->dumpLOGV(buf);
192 }
193 }
194
ElementState()195 ElementState::ElementState()
196 {
197 }
198
~ElementState()199 ElementState::~ElementState()
200 {
201 }
202
203 /////////////////////////////////////////
204 //
205
206 namespace android {
207 namespace renderscript {
208
rsi_ElementBegin(Context * rsc)209 void rsi_ElementBegin(Context *rsc)
210 {
211 rsc->mStateElement.mComponentBuildList.clear();
212 }
213
rsi_ElementAdd(Context * rsc,RsDataKind dk,RsDataType dt,bool isNormalized,size_t bits,const char * name)214 void rsi_ElementAdd(Context *rsc, RsDataKind dk, RsDataType dt, bool isNormalized, size_t bits, const char *name)
215 {
216 ElementState * sec = &rsc->mStateElement;
217
218 rsAssert(bits > 0);
219
220 Component *c = new Component(rsc,
221 static_cast<Component::DataKind>(dk),
222 static_cast<Component::DataType>(dt),
223 isNormalized,
224 bits,
225 name);
226 sec->mComponentBuildList.add(c);
227 }
228
rsi_ElementCreate(Context * rsc)229 RsElement rsi_ElementCreate(Context *rsc)
230 {
231 ElementState * sec = &rsc->mStateElement;
232 Element *se = new Element(rsc, sec->mComponentBuildList.size());
233
234 rsAssert(se->getComponentCount() > 0);
235
236 for (size_t ct = 0; ct < se->getComponentCount(); ct++) {
237 se->setComponent(ct, sec->mComponentBuildList[ct]);
238 }
239
240 rsc->mStateElement.mComponentBuildList.clear();
241 se->incUserRef();
242 return se;
243 }
244
245
246 }
247 }
248