• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 #if !defined(RS_SERVER) && !defined(RS_COMPATIBILITY_LIB)
20 #include "system/graphics.h"
21 #endif
22 
23 #ifdef RS_COMPATIBILITY_LIB
24 #include "rsCompatibilityLib.h"
25 #endif
26 
27 using namespace android;
28 using namespace android::renderscript;
29 
Type(Context * rsc)30 Type::Type(Context *rsc) : ObjectBase(rsc) {
31     memset(&mHal, 0, sizeof(mHal));
32     mDimLOD = false;
33 }
34 
preDestroy() const35 void Type::preDestroy() const {
36     for (uint32_t ct = 0; ct < mRSC->mStateType.mTypes.size(); ct++) {
37         if (mRSC->mStateType.mTypes[ct] == this) {
38             mRSC->mStateType.mTypes.removeAt(ct);
39             break;
40         }
41     }
42 }
43 
~Type()44 Type::~Type() {
45     clear();
46 }
47 
operator delete(void * ptr)48 void Type::operator delete(void* ptr) {
49     if (ptr) {
50         Type *t = (Type*) ptr;
51         t->getContext()->mHal.funcs.freeRuntimeMem(ptr);
52     }
53 }
54 
clear()55 void Type::clear() {
56     if (mHal.state.lodCount) {
57         delete [] mHal.state.lodDimX;
58         delete [] mHal.state.lodDimY;
59         delete [] mHal.state.lodDimZ;
60     }
61     mElement.clear();
62     memset(&mHal, 0, sizeof(mHal));
63 }
64 
TypeState()65 TypeState::TypeState() {
66 }
67 
~TypeState()68 TypeState::~TypeState() {
69     rsAssert(!mTypes.size());
70 }
71 
compute()72 void Type::compute() {
73     uint32_t oldLODCount = mHal.state.lodCount;
74     if (mDimLOD) {
75         uint32_t l2x = rsFindHighBit(mHal.state.dimX) + 1;
76         uint32_t l2y = rsFindHighBit(mHal.state.dimY) + 1;
77         uint32_t l2z = rsFindHighBit(mHal.state.dimZ) + 1;
78 
79         mHal.state.lodCount = rsMax(l2x, l2y);
80         mHal.state.lodCount = rsMax(mHal.state.lodCount, l2z);
81     } else {
82         if (mHal.state.dimYuv) {
83             mHal.state.lodCount = 3;
84         } else {
85             mHal.state.lodCount = 1;
86         }
87     }
88     if (mHal.state.lodCount != oldLODCount) {
89         if (oldLODCount) {
90             delete [] mHal.state.lodDimX;
91             delete [] mHal.state.lodDimY;
92             delete [] mHal.state.lodDimZ;
93         }
94         mHal.state.lodDimX = new uint32_t[mHal.state.lodCount];
95         mHal.state.lodDimY = new uint32_t[mHal.state.lodCount];
96         mHal.state.lodDimZ = new uint32_t[mHal.state.lodCount];
97     }
98 
99     uint32_t tx = mHal.state.dimX;
100     uint32_t ty = mHal.state.dimY;
101     uint32_t tz = mHal.state.dimZ;
102     mCellCount = 0;
103     if (!mHal.state.dimYuv) {
104         for (uint32_t lod=0; lod < mHal.state.lodCount; lod++) {
105             mHal.state.lodDimX[lod] = tx;
106             mHal.state.lodDimY[lod] = ty;
107             mHal.state.lodDimZ[lod]  = tz;
108             mCellCount += tx * rsMax(ty, 1u) * rsMax(tz, 1u);
109             if (tx > 1) tx >>= 1;
110             if (ty > 1) ty >>= 1;
111             if (tz > 1) tz >>= 1;
112         }
113     }
114 
115     if (mHal.state.faces) {
116         mCellCount *= 6;
117     }
118 #ifndef RS_SERVER
119     // YUV only supports basic 2d
120     // so we can stash the plane pointers in the mipmap levels.
121     if (mHal.state.dimYuv) {
122         mHal.state.lodDimX[1] = mHal.state.lodDimX[0] / 2;
123         mHal.state.lodDimY[1] = mHal.state.lodDimY[0] / 2;
124         mHal.state.lodDimX[2] = mHal.state.lodDimX[0] / 2;
125         mHal.state.lodDimY[2] = mHal.state.lodDimY[0] / 2;
126         mCellCount += mHal.state.lodDimX[0] * mHal.state.lodDimY[0];
127         mCellCount += mHal.state.lodDimX[1] * mHal.state.lodDimY[1];
128         mCellCount += mHal.state.lodDimX[2] * mHal.state.lodDimY[2];
129 
130         switch(mHal.state.dimYuv) {
131         case HAL_PIXEL_FORMAT_YV12:
132             break;
133         case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // NV21
134             mHal.state.lodDimX[1] = mHal.state.lodDimX[0];
135             break;
136 #ifndef RS_COMPATIBILITY_LIB
137         case HAL_PIXEL_FORMAT_YCbCr_420_888:
138             break;
139 #endif
140         default:
141             rsAssert(0);
142         }
143     }
144 #endif
145     mHal.state.element = mElement.get();
146 }
147 
dumpLOGV(const char * prefix) const148 void Type::dumpLOGV(const char *prefix) const {
149     char buf[1024];
150     ObjectBase::dumpLOGV(prefix);
151     ALOGV("%s   Type: x=%u y=%u z=%u mip=%i face=%i", prefix,
152                                                       mHal.state.dimX,
153                                                       mHal.state.dimY,
154                                                       mHal.state.dimZ,
155                                                       mHal.state.lodCount,
156                                                       mHal.state.faces);
157     snprintf(buf, sizeof(buf), "%s element: ", prefix);
158     mElement->dumpLOGV(buf);
159 }
160 
serialize(Context * rsc,OStream * stream) const161 void Type::serialize(Context *rsc, OStream *stream) const {
162     // Need to identify ourselves
163     stream->addU32((uint32_t)getClassId());
164     stream->addString(getName());
165 
166     mElement->serialize(rsc, stream);
167 
168     stream->addU32(mHal.state.dimX);
169     stream->addU32(mHal.state.dimY);
170     stream->addU32(mHal.state.dimZ);
171 
172     stream->addU8((uint8_t)(mHal.state.lodCount ? 1 : 0));
173     stream->addU8((uint8_t)(mHal.state.faces ? 1 : 0));
174 }
175 
createFromStream(Context * rsc,IStream * stream)176 Type *Type::createFromStream(Context *rsc, IStream *stream) {
177     // First make sure we are reading the correct object
178     RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
179     if (classID != RS_A3D_CLASS_ID_TYPE) {
180         ALOGE("type loading skipped due to invalid class id\n");
181         return NULL;
182     }
183 
184     const char *name = stream->loadString();
185 
186     Element *elem = Element::createFromStream(rsc, stream);
187     if (!elem) {
188         return NULL;
189     }
190 
191     uint32_t x = stream->loadU32();
192     uint32_t y = stream->loadU32();
193     uint32_t z = stream->loadU32();
194     uint8_t lod = stream->loadU8();
195     uint8_t faces = stream->loadU8();
196     Type *type = Type::getType(rsc, elem, x, y, z, lod != 0, faces !=0, 0);
197     elem->decUserRef();
198 
199     delete [] name;
200     return type;
201 }
202 
getIsNp2() const203 bool Type::getIsNp2() const {
204     uint32_t x = getDimX();
205     uint32_t y = getDimY();
206     uint32_t z = getDimZ();
207 
208     if (x && (x & (x-1))) {
209         return true;
210     }
211     if (y && (y & (y-1))) {
212         return true;
213     }
214     if (z && (z & (z-1))) {
215         return true;
216     }
217     return false;
218 }
219 
getTypeRef(Context * rsc,const Element * e,uint32_t dimX,uint32_t dimY,uint32_t dimZ,bool dimLOD,bool dimFaces,uint32_t dimYuv)220 ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e,
221                                      uint32_t dimX, uint32_t dimY, uint32_t dimZ,
222                                      bool dimLOD, bool dimFaces, uint32_t dimYuv) {
223     ObjectBaseRef<Type> returnRef;
224 
225     TypeState * stc = &rsc->mStateType;
226 
227     ObjectBase::asyncLock();
228     for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
229         Type *t = stc->mTypes[ct];
230         if (t->getElement() != e) continue;
231         if (t->getDimX() != dimX) continue;
232         if (t->getDimY() != dimY) continue;
233         if (t->getDimZ() != dimZ) continue;
234         if (t->getDimLOD() != dimLOD) continue;
235         if (t->getDimFaces() != dimFaces) continue;
236         if (t->getDimYuv() != dimYuv) continue;
237         returnRef.set(t);
238         ObjectBase::asyncUnlock();
239         return returnRef;
240     }
241     ObjectBase::asyncUnlock();
242 
243     // Type objects must use allocator specified by the driver
244     void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Type), 0);
245     if (!allocMem) {
246         rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Type");
247         return NULL;
248     }
249 
250     Type *nt = new (allocMem) Type(rsc);
251 
252 #ifdef RS_FIND_OFFSETS
253     ALOGE("pointer for type: %p", nt);
254     ALOGE("pointer for type.drv: %p", &nt->mHal.drv);
255 #endif
256 
257     nt->mDimLOD = dimLOD;
258     returnRef.set(nt);
259     nt->mElement.set(e);
260     nt->mHal.state.dimX = dimX;
261     nt->mHal.state.dimY = dimY;
262     nt->mHal.state.dimZ = dimZ;
263     nt->mHal.state.faces = dimFaces;
264     nt->mHal.state.dimYuv = dimYuv;
265     nt->compute();
266 
267     ObjectBase::asyncLock();
268     stc->mTypes.push(nt);
269     ObjectBase::asyncUnlock();
270 
271     return returnRef;
272 }
273 
cloneAndResize1D(Context * rsc,uint32_t dimX) const274 ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
275     return getTypeRef(rsc, mElement.get(), dimX,
276                       getDimY(), getDimZ(), getDimLOD(), getDimFaces(), getDimYuv());
277 }
278 
cloneAndResize2D(Context * rsc,uint32_t dimX,uint32_t dimY) const279 ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
280                               uint32_t dimX,
281                               uint32_t dimY) const {
282     return getTypeRef(rsc, mElement.get(), dimX, dimY,
283                       getDimZ(), getDimLOD(), getDimFaces(), getDimYuv());
284 }
285 
286 
incRefs(const void * ptr,size_t ct,size_t startOff) const287 void Type::incRefs(const void *ptr, size_t ct, size_t startOff) const {
288     const uint8_t *p = static_cast<const uint8_t *>(ptr);
289     const Element *e = mHal.state.element;
290     uint32_t stride = e->getSizeBytes();
291 
292     p += stride * startOff;
293     while (ct > 0) {
294         e->incRefs(p);
295         ct--;
296         p += stride;
297     }
298 }
299 
300 
decRefs(const void * ptr,size_t ct,size_t startOff) const301 void Type::decRefs(const void *ptr, size_t ct, size_t startOff) const {
302     if (!mHal.state.element->getHasReferences()) {
303         return;
304     }
305     const uint8_t *p = static_cast<const uint8_t *>(ptr);
306     const Element *e = mHal.state.element;
307     uint32_t stride = e->getSizeBytes();
308 
309     p += stride * startOff;
310     while (ct > 0) {
311         e->decRefs(p);
312         ct--;
313         p += stride;
314     }
315 }
316 
callUpdateCacheObject(const Context * rsc,void * dstObj) const317 void Type::callUpdateCacheObject(const Context *rsc, void *dstObj) const {
318     if (rsc->mHal.funcs.type.updateCachedObject != NULL) {
319         rsc->mHal.funcs.type.updateCachedObject(rsc, this, (rs_type *)dstObj);
320     } else {
321         *((const void **)dstObj) = this;
322     }
323 }
324 
325 //////////////////////////////////////////////////
326 //
327 namespace android {
328 namespace renderscript {
329 
rsi_TypeCreate(Context * rsc,RsElement _e,uint32_t dimX,uint32_t dimY,uint32_t dimZ,bool mipmaps,bool faces,uint32_t yuv)330 RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX,
331                      uint32_t dimY, uint32_t dimZ, bool mipmaps, bool faces, uint32_t yuv) {
332     Element *e = static_cast<Element *>(_e);
333 
334     return Type::getType(rsc, e, dimX, dimY, dimZ, mipmaps, faces, yuv);
335 }
336 
337 }
338 }
339 
rsaTypeGetNativeData(RsContext con,RsType type,uintptr_t * typeData,uint32_t typeDataSize)340 extern "C" void rsaTypeGetNativeData(RsContext con, RsType type, uintptr_t *typeData, uint32_t typeDataSize) {
341     rsAssert(typeDataSize == 6);
342     // Pack the data in the follofing way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
343     // mHal.state.lodCount; mHal.state.faces; mElement; into typeData
344     Type *t = static_cast<Type *>(type);
345 
346     (*typeData++) = t->getDimX();
347     (*typeData++) = t->getDimY();
348     (*typeData++) = t->getDimZ();
349     (*typeData++) = t->getDimLOD() ? 1 : 0;
350     (*typeData++) = t->getDimFaces() ? 1 : 0;
351     (*typeData++) = (uintptr_t)t->getElement();
352     t->getElement()->incUserRef();
353 }
354