blob: 396018bdc3adec8915623b6ecfe927efefa8f968 [file] [log] [blame]
Jason Sams221a4b12012-02-22 15:22:41 -08001/*
Jason Sams3522f402012-03-23 11:47:26 -07002 * Copyright (C) 2012 The Android Open Source Project
Jason Sams221a4b12012-02-22 15:22:41 -08003 *
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
Jason Sams221a4b12012-02-22 15:22:41 -080017#include "RenderScript.h"
Jason Sams221a4b12012-02-22 15:22:41 -080018
Jason Sams69cccdf2012-04-02 19:11:49 -070019using namespace android;
20using namespace renderscriptCpp;
Jason Sams221a4b12012-02-22 15:22:41 -080021
22void * Allocation::getIDSafe() const {
Jason Sams221a4b12012-02-22 15:22:41 -080023 return getID();
24}
25
Jason Sams69cccdf2012-04-02 19:11:49 -070026void Allocation::updateCacheInfo(sp<const Type> t) {
Jason Sams221a4b12012-02-22 15:22:41 -080027 mCurrentDimX = t->getX();
28 mCurrentDimY = t->getY();
29 mCurrentDimZ = t->getZ();
30 mCurrentCount = mCurrentDimX;
31 if (mCurrentDimY > 1) {
32 mCurrentCount *= mCurrentDimY;
33 }
34 if (mCurrentDimZ > 1) {
35 mCurrentCount *= mCurrentDimZ;
36 }
37}
38
Tim Murray84bf2b82012-10-31 16:03:16 -070039Allocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) :
Jason Sams69cccdf2012-04-02 19:11:49 -070040 BaseObj(id, rs) {
41
Jason Sams221a4b12012-02-22 15:22:41 -080042 if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT |
43 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
44 RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
45 RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
46 RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
Jason Sams221a4b12012-02-22 15:22:41 -080047 RS_ALLOCATION_USAGE_IO_INPUT |
48 RS_ALLOCATION_USAGE_IO_OUTPUT)) != 0) {
49 ALOGE("Unknown usage specified.");
50 }
51
Jason Sams3522f402012-03-23 11:47:26 -070052 if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) {
Jason Sams221a4b12012-02-22 15:22:41 -080053 mWriteAllowed = false;
Jason Sams3522f402012-03-23 11:47:26 -070054 if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT |
Jason Sams221a4b12012-02-22 15:22:41 -080055 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
56 RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
57 ALOGE("Invalid usage combination.");
58 }
59 }
60
61 mType = t;
62 mUsage = usage;
63
Jason Sams69cccdf2012-04-02 19:11:49 -070064 if (t.get() != NULL) {
Jason Sams221a4b12012-02-22 15:22:41 -080065 updateCacheInfo(t);
66 }
67}
68
69void Allocation::validateIsInt32() {
70 RsDataType dt = mType->getElement()->getDataType();
71 if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
72 return;
73 }
74 ALOGE("32 bit integer source does not match allocation type %i", dt);
75}
76
77void Allocation::validateIsInt16() {
78 RsDataType dt = mType->getElement()->getDataType();
79 if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) {
80 return;
81 }
82 ALOGE("16 bit integer source does not match allocation type %i", dt);
83}
84
85void Allocation::validateIsInt8() {
86 RsDataType dt = mType->getElement()->getDataType();
87 if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) {
88 return;
89 }
90 ALOGE("8 bit integer source does not match allocation type %i", dt);
91}
92
93void Allocation::validateIsFloat32() {
94 RsDataType dt = mType->getElement()->getDataType();
95 if (dt == RS_TYPE_FLOAT_32) {
96 return;
97 }
98 ALOGE("32 bit float source does not match allocation type %i", dt);
99}
100
101void Allocation::validateIsObject() {
102 RsDataType dt = mType->getElement()->getDataType();
103 if ((dt == RS_TYPE_ELEMENT) ||
104 (dt == RS_TYPE_TYPE) ||
105 (dt == RS_TYPE_ALLOCATION) ||
106 (dt == RS_TYPE_SAMPLER) ||
107 (dt == RS_TYPE_SCRIPT) ||
108 (dt == RS_TYPE_MESH) ||
109 (dt == RS_TYPE_PROGRAM_FRAGMENT) ||
110 (dt == RS_TYPE_PROGRAM_VERTEX) ||
111 (dt == RS_TYPE_PROGRAM_RASTER) ||
112 (dt == RS_TYPE_PROGRAM_STORE)) {
113 return;
114 }
115 ALOGE("Object source does not match allocation type %i", dt);
116}
117
118void Allocation::updateFromNative() {
119 BaseObj::updateFromNative();
120
Tim Murray84bf2b82012-10-31 16:03:16 -0700121 const void *typeID = rsaAllocationGetType(mRS->getContext(), getID());
Jason Sams221a4b12012-02-22 15:22:41 -0800122 if(typeID != NULL) {
Jason Sams69cccdf2012-04-02 19:11:49 -0700123 sp<const Type> old = mType;
124 sp<Type> t = new Type((void *)typeID, mRS);
Jason Sams221a4b12012-02-22 15:22:41 -0800125 t->updateFromNative();
126 updateCacheInfo(t);
127 mType = t;
Jason Sams221a4b12012-02-22 15:22:41 -0800128 }
129}
130
131void Allocation::syncAll(RsAllocationUsageType srcLocation) {
132 switch (srcLocation) {
133 case RS_ALLOCATION_USAGE_SCRIPT:
134 case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS:
135 case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE:
136 case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX:
137 break;
138 default:
139 ALOGE("Source must be exactly one usage type.");
140 }
Tim Murray84bf2b82012-10-31 16:03:16 -0700141 rsAllocationSyncAll(mRS->getContext(), getIDSafe(), srcLocation);
Jason Sams221a4b12012-02-22 15:22:41 -0800142}
143
144void Allocation::ioSendOutput() {
145 if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
146 ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
147 }
Tim Murray84bf2b82012-10-31 16:03:16 -0700148 rsAllocationIoSend(mRS->getContext(), getID());
Jason Sams221a4b12012-02-22 15:22:41 -0800149}
150
151void Allocation::ioGetInput() {
152 if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
153 ALOGE("Can only send buffer if IO_OUTPUT usage specified.");
154 }
Tim Murray84bf2b82012-10-31 16:03:16 -0700155 rsAllocationIoReceive(mRS->getContext(), getID());
Jason Sams221a4b12012-02-22 15:22:41 -0800156}
157
Jason Sams221a4b12012-02-22 15:22:41 -0800158void Allocation::generateMipmaps() {
Tim Murray84bf2b82012-10-31 16:03:16 -0700159 rsAllocationGenerateMipmaps(mRS->getContext(), getID());
Jason Sams221a4b12012-02-22 15:22:41 -0800160}
161
Jason Sams69cccdf2012-04-02 19:11:49 -0700162void Allocation::copy1DRangeFromUnchecked(uint32_t off, size_t count, const void *data,
163 size_t dataLen) {
164
Jason Sams221a4b12012-02-22 15:22:41 -0800165 if(count < 1) {
166 ALOGE("Count must be >= 1.");
167 return;
168 }
169 if((off + count) > mCurrentCount) {
170 ALOGE("Overflow, Available count %zu, got %zu at offset %zu.", mCurrentCount, count, off);
171 return;
172 }
173 if((count * mType->getElement()->getSizeBytes()) > dataLen) {
174 ALOGE("Array too small for allocation type.");
175 return;
176 }
177
Tim Murray84bf2b82012-10-31 16:03:16 -0700178 rsAllocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD, count, data, dataLen);
Jason Sams221a4b12012-02-22 15:22:41 -0800179}
180
181void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int32_t *d, size_t dataLen) {
182 validateIsInt32();
183 copy1DRangeFromUnchecked(off, count, d, dataLen);
184}
185
186void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int16_t *d, size_t dataLen) {
187 validateIsInt16();
188 copy1DRangeFromUnchecked(off, count, d, dataLen);
189}
190
191void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const int8_t *d, size_t dataLen) {
192 validateIsInt8();
193 copy1DRangeFromUnchecked(off, count, d, dataLen);
194}
195
196void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const float *d, size_t dataLen) {
197 validateIsFloat32();
198 copy1DRangeFromUnchecked(off, count, d, dataLen);
199}
200
Jason Sams69cccdf2012-04-02 19:11:49 -0700201void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const Allocation *data,
202 uint32_t dataOff) {
203
Tim Murray84bf2b82012-10-31 16:03:16 -0700204 rsAllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0,
Jason Sams221a4b12012-02-22 15:22:41 -0800205 mSelectedLOD, mSelectedFace,
206 count, 1, data->getIDSafe(), dataOff, 0,
207 data->mSelectedLOD, data->mSelectedFace);
208}
209
210void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) {
211 if (mAdaptedAllocation != NULL) {
212
213 } else {
214 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
215 ALOGE("Updated region larger than allocation.");
216 }
217 }
218}
219
220void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
221 const int8_t *data, size_t dataLen) {
222 validate2DRange(xoff, yoff, w, h);
Tim Murray84bf2b82012-10-31 16:03:16 -0700223 rsAllocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
Jason Sams221a4b12012-02-22 15:22:41 -0800224 w, h, data, dataLen);
225}
226
227void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
228 const int16_t *data, size_t dataLen) {
229 validate2DRange(xoff, yoff, w, h);
Tim Murray84bf2b82012-10-31 16:03:16 -0700230 rsAllocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
Jason Sams221a4b12012-02-22 15:22:41 -0800231 w, h, data, dataLen);
232}
233
234void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
235 const int32_t *data, size_t dataLen) {
236 validate2DRange(xoff, yoff, w, h);
Tim Murray84bf2b82012-10-31 16:03:16 -0700237 rsAllocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
Jason Sams221a4b12012-02-22 15:22:41 -0800238 w, h, data, dataLen);
239}
240
241void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
242 const float *data, size_t dataLen) {
243 validate2DRange(xoff, yoff, w, h);
Tim Murray84bf2b82012-10-31 16:03:16 -0700244 rsAllocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
Jason Sams221a4b12012-02-22 15:22:41 -0800245 w, h, data, dataLen);
246}
247
248void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
249 const Allocation *data, size_t dataLen,
250 uint32_t dataXoff, uint32_t dataYoff) {
251 validate2DRange(xoff, yoff, w, h);
Tim Murray84bf2b82012-10-31 16:03:16 -0700252 rsAllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff,
Jason Sams221a4b12012-02-22 15:22:41 -0800253 mSelectedLOD, mSelectedFace,
254 w, h, data->getIDSafe(), dataXoff, dataYoff,
255 data->mSelectedLOD, data->mSelectedFace);
256}
257
258/*
Jason Sams221a4b12012-02-22 15:22:41 -0800259void resize(int dimX) {
260 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
261 throw new RSInvalidStateException("Resize only support for 1D allocations at this time.");
262 }
263 mRS.nAllocationResize1D(getID(), dimX);
264 mRS.finish(); // Necessary because resize is fifoed and update is async.
265
266 int typeID = mRS.nAllocationGetType(getID());
267 mType = new Type(typeID, mRS);
268 mType.updateFromNative();
269 updateCacheInfo(mType);
270}
271
272void resize(int dimX, int dimY) {
273 if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
274 throw new RSInvalidStateException(
275 "Resize only support for 2D allocations at this time.");
276 }
277 if (mType.getY() == 0) {
278 throw new RSInvalidStateException(
279 "Resize only support for 2D allocations at this time.");
280 }
281 mRS.nAllocationResize2D(getID(), dimX, dimY);
282 mRS.finish(); // Necessary because resize is fifoed and update is async.
283
284 int typeID = mRS.nAllocationGetType(getID());
285 mType = new Type(typeID, mRS);
286 mType.updateFromNative();
287 updateCacheInfo(mType);
288}
289*/
290
291
Tim Murray84bf2b82012-10-31 16:03:16 -0700292android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
Jason Sams221a4b12012-02-22 15:22:41 -0800293 RsAllocationMipmapControl mips, uint32_t usage) {
Tim Murray84bf2b82012-10-31 16:03:16 -0700294 void *id = rsAllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, 0);
Jason Sams221a4b12012-02-22 15:22:41 -0800295 if (id == 0) {
296 ALOGE("Allocation creation failed.");
297 return NULL;
298 }
299 return new Allocation(id, rs, type, usage);
300}
301
Tim Murray84bf2b82012-10-31 16:03:16 -0700302android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
Jason Sams221a4b12012-02-22 15:22:41 -0800303 RsAllocationMipmapControl mips, uint32_t usage, void *pointer) {
Tim Murray84bf2b82012-10-31 16:03:16 -0700304 void *id = rsAllocationCreateTyped(rs->getContext(), type->getID(), mips, usage, (uint32_t)pointer);
Jason Sams221a4b12012-02-22 15:22:41 -0800305 if (id == 0) {
306 ALOGE("Allocation creation failed.");
307 }
308 return new Allocation(id, rs, type, usage);
309}
310
Tim Murray84bf2b82012-10-31 16:03:16 -0700311android::sp<Allocation> Allocation::createTyped(sp<RS> rs, sp<const Type> type,
Jason Sams69cccdf2012-04-02 19:11:49 -0700312 uint32_t usage) {
Jason Sams221a4b12012-02-22 15:22:41 -0800313 return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
314}
315
Tim Murray84bf2b82012-10-31 16:03:16 -0700316android::sp<Allocation> Allocation::createSized(sp<RS> rs, sp<const Element> e,
Jason Sams69cccdf2012-04-02 19:11:49 -0700317 size_t count, uint32_t usage) {
318
Jason Sams221a4b12012-02-22 15:22:41 -0800319 Type::Builder b(rs, e);
320 b.setX(count);
Jason Sams69cccdf2012-04-02 19:11:49 -0700321 sp<const Type> t = b.create();
Jason Sams221a4b12012-02-22 15:22:41 -0800322
Tim Murray84bf2b82012-10-31 16:03:16 -0700323 void *id = rsAllocationCreateTyped(rs->getContext(), t->getID(),
Jason Sams69cccdf2012-04-02 19:11:49 -0700324 RS_ALLOCATION_MIPMAP_NONE, usage, 0);
Jason Sams221a4b12012-02-22 15:22:41 -0800325 if (id == 0) {
326 ALOGE("Allocation creation failed.");
327 }
328 return new Allocation(id, rs, t, usage);
329}