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 "RenderScript.h"
18 #include "rsCppInternal.h"
19
20 using android::RSC::Allocation;
21 using android::RSC::sp;
22
getIDSafe() const23 void * Allocation::getIDSafe() const {
24 return getID();
25 }
26
updateCacheInfo(const sp<const Type> & t)27 void Allocation::updateCacheInfo(const sp<const Type>& t) {
28 mCurrentDimX = t->getX();
29 mCurrentDimY = t->getY();
30 mCurrentDimZ = t->getZ();
31 mCurrentCount = mCurrentDimX;
32 if (mCurrentDimY > 1) {
33 mCurrentCount *= mCurrentDimY;
34 }
35 if (mCurrentDimZ > 1) {
36 mCurrentCount *= mCurrentDimZ;
37 }
38 }
39
Allocation(void * id,sp<RS> rs,sp<const Type> t,uint32_t usage)40 Allocation::Allocation(void *id, sp<RS> rs, sp<const Type> t, uint32_t usage) :
41 BaseObj(id, rs), mSelectedY(0), mSelectedZ(0), mSelectedLOD(0),
42 mSelectedFace(RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X) {
43
44 if ((usage & ~(RS_ALLOCATION_USAGE_SCRIPT |
45 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
46 RS_ALLOCATION_USAGE_GRAPHICS_VERTEX |
47 RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS |
48 RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET |
49 RS_ALLOCATION_USAGE_IO_INPUT |
50 RS_ALLOCATION_USAGE_IO_OUTPUT |
51 RS_ALLOCATION_USAGE_OEM |
52 RS_ALLOCATION_USAGE_SHARED)) != 0) {
53 ALOGE("Unknown usage specified.");
54 }
55
56 if ((usage & RS_ALLOCATION_USAGE_IO_INPUT) != 0) {
57 mWriteAllowed = false;
58 if ((usage & ~(RS_ALLOCATION_USAGE_IO_INPUT |
59 RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE |
60 RS_ALLOCATION_USAGE_SCRIPT)) != 0) {
61 ALOGE("Invalid usage combination.");
62 }
63 }
64
65 mType = t;
66 mUsage = usage;
67 mAutoPadding = false;
68 if (t != nullptr) {
69 updateCacheInfo(t);
70 }
71
72 }
73
74
validateIsInt64()75 void Allocation::validateIsInt64() {
76 RsDataType dt = mType->getElement()->getDataType();
77 if ((dt == RS_TYPE_SIGNED_64) || (dt == RS_TYPE_UNSIGNED_64)) {
78 return;
79 }
80 ALOGE("64 bit integer source does not match allocation type %i", dt);
81 }
82
validateIsInt32()83 void Allocation::validateIsInt32() {
84 RsDataType dt = mType->getElement()->getDataType();
85 if ((dt == RS_TYPE_SIGNED_32) || (dt == RS_TYPE_UNSIGNED_32)) {
86 return;
87 }
88 ALOGE("32 bit integer source does not match allocation type %i", dt);
89 }
90
validateIsInt16()91 void Allocation::validateIsInt16() {
92 RsDataType dt = mType->getElement()->getDataType();
93 if ((dt == RS_TYPE_SIGNED_16) || (dt == RS_TYPE_UNSIGNED_16)) {
94 return;
95 }
96 ALOGE("16 bit integer source does not match allocation type %i", dt);
97 }
98
validateIsInt8()99 void Allocation::validateIsInt8() {
100 RsDataType dt = mType->getElement()->getDataType();
101 if ((dt == RS_TYPE_SIGNED_8) || (dt == RS_TYPE_UNSIGNED_8)) {
102 return;
103 }
104 ALOGE("8 bit integer source does not match allocation type %i", dt);
105 }
106
validateIsFloat32()107 void Allocation::validateIsFloat32() {
108 RsDataType dt = mType->getElement()->getDataType();
109 if (dt == RS_TYPE_FLOAT_32) {
110 return;
111 }
112 ALOGE("32 bit float source does not match allocation type %i", dt);
113 }
114
validateIsFloat64()115 void Allocation::validateIsFloat64() {
116 RsDataType dt = mType->getElement()->getDataType();
117 if (dt == RS_TYPE_FLOAT_64) {
118 return;
119 }
120 ALOGE("64 bit float source does not match allocation type %i", dt);
121 }
122
validateIsObject()123 void Allocation::validateIsObject() {
124 RsDataType dt = mType->getElement()->getDataType();
125 if ((dt == RS_TYPE_ELEMENT) ||
126 (dt == RS_TYPE_TYPE) ||
127 (dt == RS_TYPE_ALLOCATION) ||
128 (dt == RS_TYPE_SAMPLER) ||
129 (dt == RS_TYPE_SCRIPT) ||
130 (dt == RS_TYPE_MESH) ||
131 (dt == RS_TYPE_PROGRAM_FRAGMENT) ||
132 (dt == RS_TYPE_PROGRAM_VERTEX) ||
133 (dt == RS_TYPE_PROGRAM_RASTER) ||
134 (dt == RS_TYPE_PROGRAM_STORE)) {
135 return;
136 }
137 ALOGE("Object source does not match allocation type %i", dt);
138 }
139
updateFromNative()140 void Allocation::updateFromNative() {
141 BaseObj::updateFromNative();
142
143 const void *typeID = RS::dispatch->AllocationGetType(mRS->getContext(), getID());
144 if(typeID != nullptr) {
145 sp<Type> t = new Type((void *)typeID, mRS);
146 t->updateFromNative();
147 updateCacheInfo(t);
148 mType = t;
149 }
150 }
151
syncAll(RsAllocationUsageType srcLocation)152 void Allocation::syncAll(RsAllocationUsageType srcLocation) {
153 switch (srcLocation) {
154 case RS_ALLOCATION_USAGE_SCRIPT:
155 case RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS:
156 case RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE:
157 case RS_ALLOCATION_USAGE_GRAPHICS_VERTEX:
158 case RS_ALLOCATION_USAGE_SHARED:
159 break;
160 default:
161 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Source must be exactly one usage type.");
162 return;
163 }
164 tryDispatch(mRS, RS::dispatch->AllocationSyncAll(mRS->getContext(), getIDSafe(), srcLocation));
165 }
166
getPointer(size_t * stride)167 void * Allocation::getPointer(size_t *stride) {
168 void *p = nullptr;
169 if (!(mUsage & RS_ALLOCATION_USAGE_SHARED)) {
170 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Allocation does not support USAGE_SHARED.");
171 return nullptr;
172 }
173
174 // FIXME: decide if lack of getPointer should cause compat mode
175 if (RS::dispatch->AllocationGetPointer == nullptr) {
176 mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Can't use getPointer on older APIs");
177 return nullptr;
178 }
179
180 p = RS::dispatch->AllocationGetPointer(mRS->getContext(), getIDSafe(), 0,
181 RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, stride, sizeof(size_t));
182 if (mRS->getError() != RS_SUCCESS) {
183 mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation lock failed");
184 p = nullptr;
185 }
186 return p;
187 }
188
189 // ---------------------------------------------------------------------------
190 //Functions needed for autopadding & unpadding
copyWithPadding(void * ptr,const void * srcPtr,int mSize,int count)191 static void copyWithPadding(void* ptr, const void* srcPtr, int mSize, int count) {
192 int sizeBytesPad = mSize * 4;
193 int sizeBytes = mSize * 3;
194 uint8_t *dst = static_cast<uint8_t *>(ptr);
195 const uint8_t *src = static_cast<const uint8_t *>(srcPtr);
196 for (int i = 0; i < count; i++) {
197 memcpy(dst, src, sizeBytes);
198 dst += sizeBytesPad;
199 src += sizeBytes;
200 }
201 }
202
copyWithUnPadding(void * ptr,const void * srcPtr,int mSize,int count)203 static void copyWithUnPadding(void* ptr, const void* srcPtr, int mSize, int count) {
204 int sizeBytesPad = mSize * 4;
205 int sizeBytes = mSize * 3;
206 uint8_t *dst = static_cast<uint8_t *>(ptr);
207 const uint8_t *src = static_cast<const uint8_t *>(srcPtr);
208 for (int i = 0; i < count; i++) {
209 memcpy(dst, src, sizeBytes);
210 dst += sizeBytes;
211 src += sizeBytesPad;
212 }
213 }
214 // ---------------------------------------------------------------------------
215
copy1DRangeFrom(uint32_t off,size_t count,const void * data)216 void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) {
217
218 if(count < 1) {
219 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Count must be >= 1.");
220 return;
221 }
222 if((off + count) > mCurrentCount) {
223 ALOGE("Overflow, Available count %u, got %zu at offset %u.", mCurrentCount, count, off);
224 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid copy specified");
225 return;
226 }
227 if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
228 size_t eSize = mType->getElement()->getSizeBytes();
229 void *ptr = malloc(eSize * count);
230 copyWithPadding(ptr, data, eSize / 4, count);
231 tryDispatch(mRS, RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
232 count, ptr, count * mType->getElement()->getSizeBytes()));
233 free(ptr);
234 } else {
235 tryDispatch(mRS, RS::dispatch->Allocation1DData(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
236 count, data, count * mType->getElement()->getSizeBytes()));
237 }
238 }
239
copy1DRangeTo(uint32_t off,size_t count,void * data)240 void Allocation::copy1DRangeTo(uint32_t off, size_t count, void *data) {
241 if(count < 1) {
242 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Count must be >= 1.");
243 return;
244 }
245 if((off + count) > mCurrentCount) {
246 ALOGE("Overflow, Available count %u, got %zu at offset %u.", mCurrentCount, count, off);
247 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Invalid copy specified");
248 return;
249 }
250 if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
251 size_t eSize = mType->getElement()->getSizeBytes();
252 void *ptr = malloc(eSize * count);
253 tryDispatch(mRS, RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
254 count, ptr, count * mType->getElement()->getSizeBytes()));
255 copyWithUnPadding(data, ptr, eSize / 4, count);
256 free(ptr);
257 } else {
258 tryDispatch(mRS, RS::dispatch->Allocation1DRead(mRS->getContext(), getIDSafe(), off, mSelectedLOD,
259 count, data, count * mType->getElement()->getSizeBytes()));
260 }
261 }
262
copy1DRangeFrom(uint32_t off,size_t count,const sp<const Allocation> & data,uint32_t dataOff)263 void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const sp<const Allocation>& data,
264 uint32_t dataOff) {
265
266 tryDispatch(mRS, RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), off, 0,
267 mSelectedLOD, mSelectedFace,
268 count, 1, data->getIDSafe(), dataOff, 0,
269 data->mSelectedLOD, data->mSelectedFace));
270 }
271
copy1DFrom(const void * data)272 void Allocation::copy1DFrom(const void* data) {
273 copy1DRangeFrom(0, mCurrentCount, data);
274 }
275
copy1DTo(void * data)276 void Allocation::copy1DTo(void* data) {
277 copy1DRangeTo(0, mCurrentCount, data);
278 }
279
280
validate2DRange(uint32_t xoff,uint32_t yoff,uint32_t w,uint32_t h)281 void Allocation::validate2DRange(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h) {
282 if (mAdaptedAllocation != nullptr) {
283
284 } else {
285 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
286 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Updated region larger than allocation.");
287 }
288 }
289 }
290
copy2DRangeFrom(uint32_t xoff,uint32_t yoff,uint32_t w,uint32_t h,const void * data)291 void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
292 const void *data) {
293 validate2DRange(xoff, yoff, w, h);
294 if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
295 size_t eSize = mType->getElement()->getSizeBytes();
296 void *ptr = malloc(eSize * w * h);
297 copyWithPadding(ptr, data, eSize / 4, w * h);
298 tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff,
299 yoff, mSelectedLOD, mSelectedFace,
300 w, h, ptr, w * h * mType->getElement()->getSizeBytes(),
301 w * mType->getElement()->getSizeBytes()));
302 free(ptr);
303 } else {
304 tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff,
305 yoff, mSelectedLOD, mSelectedFace,
306 w, h, data, w * h * mType->getElement()->getSizeBytes(),
307 w * mType->getElement()->getSizeBytes()));
308 }
309 }
310
copy2DRangeFrom(uint32_t xoff,uint32_t yoff,uint32_t w,uint32_t h,const sp<const Allocation> & data,uint32_t dataXoff,uint32_t dataYoff)311 void Allocation::copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
312 const sp<const Allocation>& data, uint32_t dataXoff, uint32_t dataYoff) {
313 validate2DRange(xoff, yoff, w, h);
314 tryDispatch(mRS, RS::dispatch->AllocationCopy2DRange(mRS->getContext(), getIDSafe(), xoff, yoff,
315 mSelectedLOD, mSelectedFace,
316 w, h, data->getIDSafe(), dataXoff, dataYoff,
317 data->mSelectedLOD, data->mSelectedFace));
318 }
319
copy2DRangeTo(uint32_t xoff,uint32_t yoff,uint32_t w,uint32_t h,void * data)320 void Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
321 void* data) {
322 validate2DRange(xoff, yoff, w, h);
323 if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
324 size_t eSize = mType->getElement()->getSizeBytes();
325 void *ptr = malloc(eSize * w * h);
326 tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
327 mSelectedLOD, mSelectedFace, w, h, ptr,
328 w * h * mType->getElement()->getSizeBytes(),
329 w * mType->getElement()->getSizeBytes()));
330 copyWithUnPadding(data, ptr, eSize / 4, w * h);
331 free(ptr);
332 } else {
333 tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
334 mSelectedLOD, mSelectedFace, w, h, data,
335 w * h * mType->getElement()->getSizeBytes(),
336 w * mType->getElement()->getSizeBytes()));
337 }
338 }
339
copy2DStridedFrom(uint32_t xoff,uint32_t yoff,uint32_t w,uint32_t h,const void * data,size_t stride)340 void Allocation::copy2DStridedFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
341 const void *data, size_t stride) {
342 validate2DRange(xoff, yoff, w, h);
343 tryDispatch(mRS, RS::dispatch->Allocation2DData(mRS->getContext(), getIDSafe(), xoff, yoff,
344 mSelectedLOD, mSelectedFace, w, h, data,
345 w * h * mType->getElement()->getSizeBytes(), stride));
346 }
347
copy2DStridedFrom(const void * data,size_t stride)348 void Allocation::copy2DStridedFrom(const void* data, size_t stride) {
349 copy2DStridedFrom(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
350 }
351
copy2DStridedTo(uint32_t xoff,uint32_t yoff,uint32_t w,uint32_t h,void * data,size_t stride)352 void Allocation::copy2DStridedTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
353 void *data, size_t stride) {
354 validate2DRange(xoff, yoff, w, h);
355 tryDispatch(mRS, RS::dispatch->Allocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff,
356 mSelectedLOD, mSelectedFace, w, h, data,
357 w * h * mType->getElement()->getSizeBytes(), stride));
358 }
359
copy2DStridedTo(void * data,size_t stride)360 void Allocation::copy2DStridedTo(void* data, size_t stride) {
361 copy2DStridedTo(0, 0, mCurrentDimX, mCurrentDimY, data, stride);
362 }
363
validate3DRange(uint32_t xoff,uint32_t yoff,uint32_t zoff,uint32_t w,uint32_t h,uint32_t d)364 void Allocation::validate3DRange(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
365 uint32_t h, uint32_t d) {
366 if (mAdaptedAllocation != nullptr) {
367
368 } else {
369 if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
370 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Updated region larger than allocation.");
371 }
372 }
373 }
374
copy3DRangeFrom(uint32_t xoff,uint32_t yoff,uint32_t zoff,uint32_t w,uint32_t h,uint32_t d,const void * data)375 void Allocation::copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
376 uint32_t h, uint32_t d, const void* data) {
377 validate3DRange(xoff, yoff, zoff, w, h, d);
378 if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
379 size_t eSize = mType->getElement()->getSizeBytes();
380 void *ptr = malloc(eSize * w * h * d);
381 copyWithPadding(ptr, data, eSize / 4, w * h * d);
382 tryDispatch(mRS, RS::dispatch->Allocation3DData(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
383 mSelectedLOD, w, h, d, ptr,
384 w * h * d * mType->getElement()->getSizeBytes(),
385 w * mType->getElement()->getSizeBytes()));
386 free(ptr);
387 } else {
388 tryDispatch(mRS, RS::dispatch->Allocation3DData(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
389 mSelectedLOD, w, h, d, data,
390 w * h * d * mType->getElement()->getSizeBytes(),
391 w * mType->getElement()->getSizeBytes()));
392 }
393 }
394
copy3DRangeFrom(uint32_t xoff,uint32_t yoff,uint32_t zoff,uint32_t w,uint32_t h,uint32_t d,const sp<const Allocation> & data,uint32_t dataXoff,uint32_t dataYoff,uint32_t dataZoff)395 void Allocation::copy3DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w, uint32_t h, uint32_t d,
396 const sp<const Allocation>& data, uint32_t dataXoff, uint32_t dataYoff, uint32_t dataZoff) {
397 validate3DRange(xoff, yoff, zoff, w, h, d);
398 tryDispatch(mRS, RS::dispatch->AllocationCopy3DRange(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
399 mSelectedLOD, w, h, d, data->getIDSafe(),
400 dataXoff, dataYoff, dataZoff, data->mSelectedLOD));
401 }
402
copy3DRangeTo(uint32_t xoff,uint32_t yoff,uint32_t zoff,uint32_t w,uint32_t h,uint32_t d,void * data)403 void Allocation::copy3DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t zoff, uint32_t w,
404 uint32_t h, uint32_t d, void* data) {
405 validate3DRange(xoff, yoff, zoff, w, h, d);
406 if (mAutoPadding && (mType->getElement()->getVectorSize() == 3)) {
407 size_t eSize = mType->getElement()->getSizeBytes();
408 void *ptr = malloc(eSize * w * h * d);
409 tryDispatch(mRS, RS::dispatch->Allocation3DRead(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
410 mSelectedLOD, w, h, d, ptr,
411 w * h * d * mType->getElement()->getSizeBytes(),
412 w * mType->getElement()->getSizeBytes()));
413 copyWithUnPadding(data, ptr, eSize / 4, w * h * d);
414 free(ptr);
415 } else {
416 tryDispatch(mRS, RS::dispatch->Allocation3DRead(mRS->getContext(), getIDSafe(), xoff, yoff, zoff,
417 mSelectedLOD, w, h, d, data,
418 w * h * d * mType->getElement()->getSizeBytes(),
419 w * mType->getElement()->getSizeBytes()));
420 }
421 }
422
createTyped(const sp<RS> & rs,const sp<const Type> & type,RsAllocationMipmapControl mipmaps,uint32_t usage)423 sp<Allocation> Allocation::createTyped(const sp<RS>& rs, const sp<const Type>& type,
424 RsAllocationMipmapControl mipmaps, uint32_t usage) {
425 void *id = 0;
426 if (rs->getError() == RS_SUCCESS) {
427 id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mipmaps, usage, 0);
428 }
429 if (id == 0) {
430 rs->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation creation failed");
431 return nullptr;
432 }
433 return new Allocation(id, rs, type, usage);
434 }
435
createTyped(const sp<RS> & rs,const sp<const Type> & type,RsAllocationMipmapControl mipmaps,uint32_t usage,void * pointer)436 sp<Allocation> Allocation::createTyped(const sp<RS>& rs, const sp<const Type>& type,
437 RsAllocationMipmapControl mipmaps, uint32_t usage,
438 void *pointer) {
439 void *id = 0;
440 if (rs->getError() == RS_SUCCESS) {
441 id = RS::dispatch->AllocationCreateTyped(rs->getContext(), type->getID(), mipmaps, usage,
442 (uintptr_t)pointer);
443 }
444 if (id == 0) {
445 rs->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation creation failed");
446 return nullptr;
447 }
448 return new Allocation(id, rs, type, usage);
449 }
450
createTyped(const sp<RS> & rs,const sp<const Type> & type,uint32_t usage)451 sp<Allocation> Allocation::createTyped(const sp<RS>& rs, const sp<const Type>& type,
452 uint32_t usage) {
453 return createTyped(rs, type, RS_ALLOCATION_MIPMAP_NONE, usage);
454 }
455
createSized(const sp<RS> & rs,const sp<const Element> & e,size_t count,uint32_t usage)456 sp<Allocation> Allocation::createSized(const sp<RS>& rs, const sp<const Element>& e,
457 size_t count, uint32_t usage) {
458 Type::Builder b(rs, e);
459 b.setX(count);
460 sp<const Type> t = b.create();
461
462 return createTyped(rs, t, usage);
463 }
464
createSized2D(const sp<RS> & rs,const sp<const Element> & e,size_t x,size_t y,uint32_t usage)465 sp<Allocation> Allocation::createSized2D(const sp<RS>& rs, const sp<const Element>& e,
466 size_t x, size_t y, uint32_t usage) {
467 Type::Builder b(rs, e);
468 b.setX(x);
469 b.setY(y);
470 sp<const Type> t = b.create();
471
472 return createTyped(rs, t, usage);
473 }
474
ioSendOutput()475 void Allocation::ioSendOutput() {
476 #ifndef RS_COMPATIBILITY_LIB
477 if ((mUsage & RS_ALLOCATION_USAGE_IO_OUTPUT) == 0) {
478 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only send buffer if IO_OUTPUT usage specified.");
479 return;
480 }
481 tryDispatch(mRS, RS::dispatch->AllocationIoSend(mRS->getContext(), getID()));
482 #endif
483 }
484
ioGetInput()485 void Allocation::ioGetInput() {
486 #ifndef RS_COMPATIBILITY_LIB
487 if ((mUsage & RS_ALLOCATION_USAGE_IO_INPUT) == 0) {
488 mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only get buffer if IO_INPUT usage specified.");
489 return;
490 }
491 tryDispatch(mRS, RS::dispatch->AllocationIoReceive(mRS->getContext(), getID()));
492 #endif
493 }
494