blob: 78b570a02f8b0a86e73de4ab086e470632b69ca4 [file] [log] [blame]
Jason Samsd19f10d2009-05-22 14:03:28 -07001/*
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 */
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070016#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Samsd19f10d2009-05-22 14:03:28 -070017#include "rsContext.h"
18
Jason Sams4b962e52009-06-22 17:15:15 -070019#include <GLES/gl.h>
Jason Samsc2908e62010-02-23 17:44:28 -080020#include <GLES2/gl2.h>
Jason Sams4b962e52009-06-22 17:15:15 -070021#include <GLES/glext.h>
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070022#else
23#include "rsContextHostStub.h"
24
25#include <OpenGL/gl.h>
26#include <OpenGl/glext.h>
27#endif
Jason Sams4b962e52009-06-22 17:15:15 -070028
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -070029#include "utils/StopWatch.h"
30
Jason Samsd19f10d2009-05-22 14:03:28 -070031using namespace android;
32using namespace android::renderscript;
33
Jason Sams5476b452010-12-08 16:14:36 -080034Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages) : ObjectBase(rsc) {
Jason Sams8a64743f2010-03-01 15:31:04 -080035 init(rsc, type);
36
Jason Sams5476b452010-12-08 16:14:36 -080037 mUsageFlags = usages;
38
Jason Sams5e0035a2010-12-13 17:11:21 -080039 allocScriptMemory();
Jason Samsee734982010-08-12 12:44:02 -070040 if (mType->getElement()->getHasReferences()) {
41 memset(mPtr, 0, mType->getSizeBytes());
42 }
Jason Sams8a64743f2010-03-01 15:31:04 -080043 if (!mPtr) {
44 LOGE("Allocation::Allocation, alloc failure");
45 }
46}
47
Jason Sams8a64743f2010-03-01 15:31:04 -080048
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080049void Allocation::init(Context *rsc, const Type *type) {
Jason Samsd19f10d2009-05-22 14:03:28 -070050 mPtr = NULL;
51
52 mCpuWrite = false;
53 mCpuRead = false;
54 mGpuWrite = false;
55 mGpuRead = false;
56
57 mReadWriteRatio = 0;
58 mUpdateSize = 0;
Jason Samsd4b23b52010-12-13 15:32:35 -080059 mUsageFlags = 0;
60 mMipmapControl = RS_ALLOCATION_MIPMAP_NONE;
Jason Samsd19f10d2009-05-22 14:03:28 -070061
Jason Samsd19f10d2009-05-22 14:03:28 -070062 mTextureID = 0;
Jason Samsd19f10d2009-05-22 14:03:28 -070063 mBufferID = 0;
Jason Sams3b7d39b2009-12-14 12:57:40 -080064 mUploadDefered = false;
Jason Samsd19f10d2009-05-22 14:03:28 -070065
Jason Sams8a64743f2010-03-01 15:31:04 -080066 mUserBitmapCallback = NULL;
67 mUserBitmapCallbackData = NULL;
68
Jason Samsd19f10d2009-05-22 14:03:28 -070069 mType.set(type);
Jason Sams1bada8c2009-08-09 17:01:55 -070070 rsAssert(type);
Jason Sams8a64743f2010-03-01 15:31:04 -080071
72 mPtr = NULL;
Jason Samsd19f10d2009-05-22 14:03:28 -070073}
74
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080075Allocation::~Allocation() {
Jason Sams8a64743f2010-03-01 15:31:04 -080076 if (mUserBitmapCallback != NULL) {
77 mUserBitmapCallback(mUserBitmapCallbackData);
Jason Sams5e0035a2010-12-13 17:11:21 -080078 mPtr = NULL;
Jason Sams8a64743f2010-03-01 15:31:04 -080079 }
Jason Sams5e0035a2010-12-13 17:11:21 -080080 freeScriptMemory();
Jason Sams9d5e03d2009-11-03 11:25:42 -080081
82 if (mBufferID) {
83 // Causes a SW crash....
84 //LOGV(" mBufferID %i", mBufferID);
85 //glDeleteBuffers(1, &mBufferID);
86 //mBufferID = 0;
87 }
88 if (mTextureID) {
89 glDeleteTextures(1, &mTextureID);
90 mTextureID = 0;
91 }
Jason Samsd19f10d2009-05-22 14:03:28 -070092}
93
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080094void Allocation::setCpuWritable(bool) {
Jason Samsd19f10d2009-05-22 14:03:28 -070095}
96
Alex Sakhartchouked9f2102010-11-09 17:00:54 -080097void Allocation::setGpuWritable(bool) {
Jason Samsd19f10d2009-05-22 14:03:28 -070098}
99
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800100void Allocation::setCpuReadable(bool) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700101}
102
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800103void Allocation::setGpuReadable(bool) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700104}
105
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800106bool Allocation::fixAllocation() {
Jason Samsd19f10d2009-05-22 14:03:28 -0700107 return false;
108}
109
Jason Sams5e0035a2010-12-13 17:11:21 -0800110void Allocation::deferedUploadToTexture(const Context *rsc) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800111 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
Jason Sams3b7d39b2009-12-14 12:57:40 -0800112 mUploadDefered = true;
113}
114
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800115uint32_t Allocation::getGLTarget() const {
Jason Samsd4b23b52010-12-13 15:32:35 -0800116 if (getIsTexture()) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800117 if (mType->getDimFaces()) {
118 return GL_TEXTURE_CUBE_MAP;
119 } else {
120 return GL_TEXTURE_2D;
121 }
122 }
Jason Samsd4b23b52010-12-13 15:32:35 -0800123 if (getIsBufferObject()) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800124 return GL_ARRAY_BUFFER;
125 }
126 return 0;
127}
128
Jason Sams5e0035a2010-12-13 17:11:21 -0800129void Allocation::allocScriptMemory() {
130 rsAssert(!mPtr);
131 mPtr = malloc(mType->getSizeBytes());
132}
133
134void Allocation::freeScriptMemory() {
135 rsAssert(!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT));
136 if (mPtr) {
137 free(mPtr);
138 mPtr = NULL;
139 }
140}
141
142
Jason Sams5476b452010-12-08 16:14:36 -0800143void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
144 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
145
Jason Samsd4b23b52010-12-13 15:32:35 -0800146 if (getIsTexture()) {
Jason Sams5476b452010-12-08 16:14:36 -0800147 uploadToTexture(rsc);
148 }
Jason Samsd4b23b52010-12-13 15:32:35 -0800149 if (getIsBufferObject()) {
Jason Sams5476b452010-12-08 16:14:36 -0800150 uploadToBufferObject(rsc);
151 }
152
153 mUploadDefered = false;
154}
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800155
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800156void Allocation::uploadToTexture(const Context *rsc) {
Jason Sams3b7d39b2009-12-14 12:57:40 -0800157
Jason Samsd4b23b52010-12-13 15:32:35 -0800158 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
Jason Sams718cd1f2009-12-23 14:35:29 -0800159 GLenum type = mType->getElement()->getComponent().getGLType();
160 GLenum format = mType->getElement()->getComponent().getGLFormat();
Jason Samse2ae85f2009-06-03 16:04:54 -0700161
162 if (!type || !format) {
163 return;
164 }
165
Jason Sams5e0035a2010-12-13 17:11:21 -0800166 if (!mPtr) {
167 return;
168 }
169
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700170 bool isFirstUpload = false;
171
Jason Samsd19f10d2009-05-22 14:03:28 -0700172 if (!mTextureID) {
173 glGenTextures(1, &mTextureID);
Jason Sams9dab6672009-11-24 12:26:35 -0800174
175 if (!mTextureID) {
176 // This should not happen, however, its likely the cause of the
177 // white sqare bug.
178 // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
179 LOGE("Upload to texture failed to gen mTextureID");
180 rsc->dumpDebug();
Jason Sams3b7d39b2009-12-14 12:57:40 -0800181 mUploadDefered = true;
182 return;
Jason Sams9dab6672009-11-24 12:26:35 -0800183 }
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700184 isFirstUpload = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700185 }
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800186
187 GLenum target = (GLenum)getGLTarget();
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800188 if (target == GL_TEXTURE_2D) {
Jason Sams5e0035a2010-12-13 17:11:21 -0800189 upload2DTexture(isFirstUpload, mPtr);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800190 } else if (target == GL_TEXTURE_CUBE_MAP) {
191 uploadCubeTexture(isFirstUpload);
192 }
193
Jason Sams5e0035a2010-12-13 17:11:21 -0800194 if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800195#ifndef ANDROID_RS_BUILD_FOR_HOST
196 glGenerateMipmap(target);
197#endif //ANDROID_RS_BUILD_FOR_HOST
198 }
199
Jason Sams5e0035a2010-12-13 17:11:21 -0800200
201 if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
202 freeScriptMemory();
203 }
204
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800205 rsc->checkError("Allocation::uploadToTexture");
206}
207
Jason Sams5e0035a2010-12-13 17:11:21 -0800208void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800209 GLenum type = mType->getElement()->getComponent().getGLType();
210 GLenum format = mType->getElement()->getComponent().getGLFormat();
211
Jason Sams5e0035a2010-12-13 17:11:21 -0800212 GLenum target = (GLenum)getGLTarget();
213 glBindTexture(target, mTextureID);
214 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Jason Samsd19f10d2009-05-22 14:03:28 -0700215
Jason Sams5e0035a2010-12-13 17:11:21 -0800216 for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
217 const uint8_t *p = (const uint8_t *)ptr;
218 p += mType->getLODOffset(lod);
219
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800220 if (isFirstUpload) {
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700221 glTexImage2D(GL_TEXTURE_2D, lod, format,
Jason Sams5e0035a2010-12-13 17:11:21 -0800222 mType->getLODDimX(lod), mType->getLODDimY(lod),
223 0, format, type, p);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700224 } else {
225 glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
Jason Sams5e0035a2010-12-13 17:11:21 -0800226 mType->getLODDimX(lod), mType->getLODDimY(lod),
227 format, type, p);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700228 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700229 }
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800230}
Jason Samsc2908e62010-02-23 17:44:28 -0800231
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800232void Allocation::uploadCubeTexture(bool isFirstUpload) {
233 GLenum type = mType->getElement()->getComponent().getGLType();
234 GLenum format = mType->getElement()->getComponent().getGLFormat();
235
Jason Sams5e0035a2010-12-13 17:11:21 -0800236 GLenum target = (GLenum)getGLTarget();
237 glBindTexture(target, mTextureID);
238 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
239
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800240 GLenum faceOrder[] = {
241 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
242 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
243 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
244 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
245 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
246 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
247 };
248
249 Adapter2D adapt(getContext(), this);
250 for (uint32_t face = 0; face < 6; face ++) {
251 adapt.setFace(face);
252
Jason Sams5e0035a2010-12-13 17:11:21 -0800253 for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
254 adapt.setLOD(lod);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800255
256 uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
257
258 if (isFirstUpload) {
259 glTexImage2D(faceOrder[face], lod, format,
260 adapt.getDimX(), adapt.getDimY(),
261 0, format, type, ptr);
262 } else {
263 glTexSubImage2D(faceOrder[face], lod, 0, 0,
264 adapt.getDimX(), adapt.getDimY(),
265 format, type, ptr);
266 }
267 }
268 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700269}
270
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800271void Allocation::deferedUploadToBufferObject(const Context *rsc) {
Jason Samsd4b23b52010-12-13 15:32:35 -0800272 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
Jason Sams3b7d39b2009-12-14 12:57:40 -0800273 mUploadDefered = true;
274}
275
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800276void Allocation::uploadToBufferObject(const Context *rsc) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700277 rsAssert(!mType->getDimY());
278 rsAssert(!mType->getDimZ());
279
Jason Samsd4b23b52010-12-13 15:32:35 -0800280 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
Jason Sams3b7d39b2009-12-14 12:57:40 -0800281
Jason Samsd19f10d2009-05-22 14:03:28 -0700282 if (!mBufferID) {
283 glGenBuffers(1, &mBufferID);
284 }
Jason Sams3b7d39b2009-12-14 12:57:40 -0800285 if (!mBufferID) {
286 LOGE("Upload to buffer object failed");
287 mUploadDefered = true;
288 return;
289 }
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800290 GLenum target = (GLenum)getGLTarget();
291 glBindBuffer(target, mBufferID);
292 glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
293 glBindBuffer(target, 0);
Jason Samsf4687002010-03-10 17:30:41 -0800294 rsc->checkError("Allocation::uploadToBufferObject");
Jason Samsd19f10d2009-05-22 14:03:28 -0700295}
296
Jason Sams5476b452010-12-08 16:14:36 -0800297void Allocation::uploadCheck(Context *rsc) {
Jason Sams3b7d39b2009-12-14 12:57:40 -0800298 if (mUploadDefered) {
Jason Sams5476b452010-12-08 16:14:36 -0800299 syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
Jason Sams3b7d39b2009-12-14 12:57:40 -0800300 }
301}
302
Jason Sams1bada8c2009-08-09 17:01:55 -0700303
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800304void Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes) {
Jason Sams07ae4062009-08-27 20:23:34 -0700305 uint32_t size = mType->getSizeBytes();
306 if (size != sizeBytes) {
307 LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
308 return;
309 }
Jason Samsb28ca96f2010-08-09 18:13:33 -0700310
311 if (mType->getElement()->getHasReferences()) {
312 incRefs(data, sizeBytes / mType->getElement()->getSizeBytes());
313 decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes());
314 }
315
Jason Sams07ae4062009-08-27 20:23:34 -0700316 memcpy(mPtr, data, size);
Jason Sams83f1c632009-10-26 15:19:28 -0700317 sendDirty();
Jason Sams3b7d39b2009-12-14 12:57:40 -0800318 mUploadDefered = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700319}
320
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800321void Allocation::read(void *data) {
Jason Sams40a29e82009-08-10 14:55:26 -0700322 memcpy(data, mPtr, mType->getSizeBytes());
323}
324
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800325void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700326 uint32_t eSize = mType->getElementSizeBytes();
327 uint8_t * ptr = static_cast<uint8_t *>(mPtr);
328 ptr += eSize * xoff;
Jason Sams07ae4062009-08-27 20:23:34 -0700329 uint32_t size = count * eSize;
330
331 if (size != sizeBytes) {
332 LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
Jason Sams3c0dfba2009-09-27 17:50:38 -0700333 mType->dumpLOGV("type info");
Jason Sams07ae4062009-08-27 20:23:34 -0700334 return;
335 }
Jason Samsb28ca96f2010-08-09 18:13:33 -0700336
337 if (mType->getElement()->getHasReferences()) {
338 incRefs(data, count);
339 decRefs(ptr, count);
340 }
341
Jason Sams07ae4062009-08-27 20:23:34 -0700342 memcpy(ptr, data, size);
Jason Sams83f1c632009-10-26 15:19:28 -0700343 sendDirty();
Jason Sams3b7d39b2009-12-14 12:57:40 -0800344 mUploadDefered = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700345}
346
Jason Sams49bdaf02010-08-31 13:50:42 -0700347void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800348 uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700349 uint32_t eSize = mType->getElementSizeBytes();
350 uint32_t lineSize = eSize * w;
351 uint32_t destW = mType->getDimX();
352
353 const uint8_t *src = static_cast<const uint8_t *>(data);
354 uint8_t *dst = static_cast<uint8_t *>(mPtr);
355 dst += eSize * (xoff + yoff * destW);
Jason Sams07ae4062009-08-27 20:23:34 -0700356
357 if ((lineSize * eSize * h) != sizeBytes) {
358 rsAssert(!"Allocation::subData called with mismatched size");
359 return;
360 }
361
Jason Samsd19f10d2009-05-22 14:03:28 -0700362 for (uint32_t line=yoff; line < (yoff+h); line++) {
Jason Samsb28ca96f2010-08-09 18:13:33 -0700363 if (mType->getElement()->getHasReferences()) {
364 incRefs(src, w);
365 decRefs(dst, w);
366 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700367 memcpy(dst, src, lineSize);
368 src += lineSize;
369 dst += destW * eSize;
370 }
Jason Sams83f1c632009-10-26 15:19:28 -0700371 sendDirty();
Jason Sams3b7d39b2009-12-14 12:57:40 -0800372 mUploadDefered = true;
Jason Samsd19f10d2009-05-22 14:03:28 -0700373}
374
Jason Sams49bdaf02010-08-31 13:50:42 -0700375void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800376 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700377}
378
Jason Sams49bdaf02010-08-31 13:50:42 -0700379void Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800380 uint32_t cIdx, uint32_t sizeBytes) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700381 uint32_t eSize = mType->getElementSizeBytes();
382 uint8_t * ptr = static_cast<uint8_t *>(mPtr);
383 ptr += eSize * x;
384
385 if (cIdx >= mType->getElement()->getFieldCount()) {
386 LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
387 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
388 return;
389 }
390
391 if (x >= mType->getDimX()) {
392 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
393 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
394 return;
395 }
396
397 const Element * e = mType->getElement()->getField(cIdx);
398 ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
399
400 if (sizeBytes != e->getSizeBytes()) {
401 LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
402 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
403 return;
404 }
405
406 if (e->getHasReferences()) {
407 e->incRefs(data);
408 e->decRefs(ptr);
409 }
410
411 memcpy(ptr, data, sizeBytes);
412 sendDirty();
413 mUploadDefered = true;
414}
415
416void Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800417 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700418 uint32_t eSize = mType->getElementSizeBytes();
419 uint8_t * ptr = static_cast<uint8_t *>(mPtr);
420 ptr += eSize * (x + y * mType->getDimX());
421
422 if (x >= mType->getDimX()) {
423 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
424 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
425 return;
426 }
427
428 if (y >= mType->getDimY()) {
429 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
430 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
431 return;
432 }
433
434 if (cIdx >= mType->getElement()->getFieldCount()) {
435 LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
436 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
437 return;
438 }
439
440 const Element * e = mType->getElement()->getField(cIdx);
441 ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
442
443 if (sizeBytes != e->getSizeBytes()) {
444 LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
445 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
446 return;
447 }
448
449 if (e->getHasReferences()) {
450 e->incRefs(data);
451 e->decRefs(ptr);
452 }
453
454 memcpy(ptr, data, sizeBytes);
455 sendDirty();
456 mUploadDefered = true;
457}
458
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800459void Allocation::addProgramToDirty(const Program *p) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700460 mToDirtyList.push(p);
Jason Sams83f1c632009-10-26 15:19:28 -0700461}
Jason Samsd19f10d2009-05-22 14:03:28 -0700462
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800463void Allocation::removeProgramToDirty(const Program *p) {
Jason Sams83f1c632009-10-26 15:19:28 -0700464 for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
465 if (mToDirtyList[ct] == p) {
466 mToDirtyList.removeAt(ct);
467 return;
468 }
469 }
470 rsAssert(0);
471}
472
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800473void Allocation::dumpLOGV(const char *prefix) const {
Jason Sams715333b2009-11-17 17:26:46 -0800474 ObjectBase::dumpLOGV(prefix);
475
476 String8 s(prefix);
477 s.append(" type ");
478 if (mType.get()) {
479 mType->dumpLOGV(s.string());
480 }
481
482 LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
483 prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
484
Jason Samsd4b23b52010-12-13 15:32:35 -0800485 LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
486 prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID);
Jason Sams715333b2009-11-17 17:26:46 -0800487}
Jason Samsd19f10d2009-05-22 14:03:28 -0700488
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800489void Allocation::serialize(OStream *stream) const {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700490 // Need to identify ourselves
491 stream->addU32((uint32_t)getClassId());
492
493 String8 name(getName());
494 stream->addString(&name);
495
496 // First thing we need to serialize is the type object since it will be needed
497 // to initialize the class
498 mType->serialize(stream);
499
500 uint32_t dataSize = mType->getSizeBytes();
501 // Write how much data we are storing
502 stream->addU32(dataSize);
503 // Now write the data
504 stream->addByteArray(mPtr, dataSize);
505}
506
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800507Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700508 // First make sure we are reading the correct object
Alex Sakhartchoukaae74ad2010-06-04 10:06:50 -0700509 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800510 if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700511 LOGE("allocation loading skipped due to invalid class id\n");
512 return NULL;
513 }
514
515 String8 name;
516 stream->loadString(&name);
517
518 Type *type = Type::createFromStream(rsc, stream);
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800519 if (!type) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700520 return NULL;
521 }
522 type->compute();
523
524 // Number of bytes we wrote out for this allocation
525 uint32_t dataSize = stream->loadU32();
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800526 if (dataSize != type->getSizeBytes()) {
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700527 LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
Jason Samsb38d5342010-10-21 14:06:55 -0700528 ObjectBase::checkDelete(type);
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700529 return NULL;
530 }
531
Jason Samsd4b23b52010-12-13 15:32:35 -0800532 Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700533 alloc->setName(name.string(), name.size());
534
535 // Read in all of our allocation data
Jason Sams49bdaf02010-08-31 13:50:42 -0700536 alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
Alex Sakhartchouk2ce0e3f2010-08-11 10:30:44 -0700537 stream->reset(stream->getPos() + dataSize);
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700538
539 return alloc;
540}
541
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800542void Allocation::sendDirty() const {
Jason Sams83f1c632009-10-26 15:19:28 -0700543 for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
544 mToDirtyList[ct]->forceDirty();
545 }
546}
Jason Samsd19f10d2009-05-22 14:03:28 -0700547
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800548void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
Jason Samsb28ca96f2010-08-09 18:13:33 -0700549 const uint8_t *p = static_cast<const uint8_t *>(ptr);
550 const Element *e = mType->getElement();
551 uint32_t stride = e->getSizeBytes();
552
Jason Sams5edc6082010-10-05 13:32:49 -0700553 p += stride * startOff;
Jason Samsb28ca96f2010-08-09 18:13:33 -0700554 while (ct > 0) {
555 e->incRefs(p);
556 ct --;
557 p += stride;
558 }
559}
560
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800561void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
Jason Samsb28ca96f2010-08-09 18:13:33 -0700562 const uint8_t *p = static_cast<const uint8_t *>(ptr);
563 const Element *e = mType->getElement();
564 uint32_t stride = e->getSizeBytes();
565
Jason Sams5edc6082010-10-05 13:32:49 -0700566 p += stride * startOff;
Jason Samsb28ca96f2010-08-09 18:13:33 -0700567 while (ct > 0) {
568 e->decRefs(p);
569 ct --;
570 p += stride;
571 }
572}
573
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800574void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
Jason Sams5edc6082010-10-05 13:32:49 -0700575}
576
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800577void Allocation::resize1D(Context *rsc, uint32_t dimX) {
Jason Sams5edc6082010-10-05 13:32:49 -0700578 Type *t = mType->cloneAndResize1D(rsc, dimX);
579
580 uint32_t oldDimX = mType->getDimX();
581 if (dimX == oldDimX) {
582 return;
583 }
584
585 if (dimX < oldDimX) {
586 decRefs(mPtr, oldDimX - dimX, dimX);
587 }
588 mPtr = realloc(mPtr, t->getSizeBytes());
589
590 if (dimX > oldDimX) {
591 const Element *e = mType->getElement();
592 uint32_t stride = e->getSizeBytes();
593 memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
594 }
595 mType.set(t);
596}
597
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800598void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
Jason Sams5edc6082010-10-05 13:32:49 -0700599 LOGE("not implemented");
600}
601
Jason Samsd19f10d2009-05-22 14:03:28 -0700602/////////////////
Jason Samse2ae85f2009-06-03 16:04:54 -0700603//
Jason Samsd19f10d2009-05-22 14:03:28 -0700604
605
606namespace android {
607namespace renderscript {
608
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800609void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700610 Allocation *alloc = static_cast<Allocation *>(va);
Jason Sams5e0035a2010-12-13 17:11:21 -0800611 alloc->deferedUploadToTexture(rsc);
Jason Samsd19f10d2009-05-22 14:03:28 -0700612}
613
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800614void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700615 Allocation *alloc = static_cast<Allocation *>(va);
Jason Sams3b7d39b2009-12-14 12:57:40 -0800616 alloc->deferedUploadToBufferObject(rsc);
Jason Samsd19f10d2009-05-22 14:03:28 -0700617}
618
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800619static void mip565(const Adapter2D &out, const Adapter2D &in) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700620 uint32_t w = out.getDimX();
621 uint32_t h = out.getDimY();
622
Jason Sams6f5c61c2009-07-28 17:20:11 -0700623 for (uint32_t y=0; y < h; y++) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700624 uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
625 const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
626 const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
627
Jason Sams6f5c61c2009-07-28 17:20:11 -0700628 for (uint32_t x=0; x < w; x++) {
Jason Samse2ae85f2009-06-03 16:04:54 -0700629 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
630 oPtr ++;
631 i1 += 2;
632 i2 += 2;
633 }
634 }
635}
636
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800637static void mip8888(const Adapter2D &out, const Adapter2D &in) {
Jason Samse2ae85f2009-06-03 16:04:54 -0700638 uint32_t w = out.getDimX();
639 uint32_t h = out.getDimY();
640
Jason Sams6f5c61c2009-07-28 17:20:11 -0700641 for (uint32_t y=0; y < h; y++) {
Jason Samse2ae85f2009-06-03 16:04:54 -0700642 uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
643 const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
644 const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
645
Jason Sams6f5c61c2009-07-28 17:20:11 -0700646 for (uint32_t x=0; x < w; x++) {
Jason Samse2ae85f2009-06-03 16:04:54 -0700647 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
Jason Samsd19f10d2009-05-22 14:03:28 -0700648 oPtr ++;
649 i1 += 2;
650 i2 += 2;
651 }
652 }
Jason Samsd19f10d2009-05-22 14:03:28 -0700653}
654
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800655static void mip8(const Adapter2D &out, const Adapter2D &in) {
Jason Samse20e3b42010-01-19 17:53:54 -0800656 uint32_t w = out.getDimX();
657 uint32_t h = out.getDimY();
658
659 for (uint32_t y=0; y < h; y++) {
660 uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
661 const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
662 const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
663
664 for (uint32_t x=0; x < w; x++) {
665 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
666 oPtr ++;
667 i1 += 2;
668 i2 += 2;
669 }
670 }
671}
672
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800673static void mip(const Adapter2D &out, const Adapter2D &in) {
674 switch (out.getBaseType()->getElement()->getSizeBits()) {
Jason Sams6f5c61c2009-07-28 17:20:11 -0700675 case 32:
676 mip8888(out, in);
677 break;
678 case 16:
679 mip565(out, in);
680 break;
Jason Samse20e3b42010-01-19 17:53:54 -0800681 case 8:
682 mip8(out, in);
683 break;
Jason Sams6f5c61c2009-07-28 17:20:11 -0700684 }
Jason Sams6f5c61c2009-07-28 17:20:11 -0700685}
Jason Samsd19f10d2009-05-22 14:03:28 -0700686
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700687#ifndef ANDROID_RS_BUILD_FOR_HOST
688
Jason Sams5476b452010-12-08 16:14:36 -0800689void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
690 Allocation *a = static_cast<Allocation *>(va);
691 a->syncAll(rsc, src);
692}
693
Jason Sams4ef66502010-12-10 16:03:15 -0800694void rsi_AllocationCopyFromBitmap(Context *rsc, RsAllocation va, const void *data, size_t dataLen) {
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700695 Allocation *texAlloc = static_cast<Allocation *>(va);
Jason Sams4ef66502010-12-10 16:03:15 -0800696 const Type * t = texAlloc->getType();
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700697
Jason Sams4ef66502010-12-10 16:03:15 -0800698 uint32_t w = t->getDimX();
699 uint32_t h = t->getDimY();
700 bool genMips = t->getDimLOD();
701 size_t s = w * h * t->getElementSizeBytes();
702 if (s != dataLen) {
703 rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
704 return;
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700705 }
Jason Sams4ef66502010-12-10 16:03:15 -0800706
Jason Sams5e0035a2010-12-13 17:11:21 -0800707 if (texAlloc->getIsScript()) {
708 memcpy(texAlloc->getPtr(), data, s);
709 if (genMips) {
710 Adapter2D adapt(rsc, texAlloc);
711 Adapter2D adapt2(rsc, texAlloc);
712 for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
713 adapt.setLOD(lod);
714 adapt2.setLOD(lod + 1);
715 mip(adapt2, adapt);
716 }
Jason Sams4ef66502010-12-10 16:03:15 -0800717 }
Jason Sams5e0035a2010-12-13 17:11:21 -0800718 } else {
719 texAlloc->upload2DTexture(false, data);
Jason Sams4ef66502010-12-10 16:03:15 -0800720 }
Jason Sams5e0035a2010-12-13 17:11:21 -0800721
Jason Sams4ef66502010-12-10 16:03:15 -0800722}
723
724void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
725 Allocation *texAlloc = static_cast<Allocation *>(va);
726 const Type * t = texAlloc->getType();
727
728 size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
729 if (s != dataLen) {
730 rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
731 return;
732 }
733
734 memcpy(data, texAlloc->getPtr(), s);
Alex Sakhartchouk26ae3902010-10-11 12:35:15 -0700735}
736
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800737void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700738 Allocation *a = static_cast<Allocation *>(va);
Jason Sams49bdaf02010-08-31 13:50:42 -0700739 a->data(rsc, data, sizeBytes);
Jason Samsd19f10d2009-05-22 14:03:28 -0700740}
741
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800742void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700743 Allocation *a = static_cast<Allocation *>(va);
Jason Sams49bdaf02010-08-31 13:50:42 -0700744 a->subData(rsc, xoff, count, data, sizeBytes);
745}
746
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800747void rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700748 Allocation *a = static_cast<Allocation *>(va);
749 a->subElementData(rsc, x, y, data, eoff, sizeBytes);
750}
751
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800752void rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes) {
Jason Sams49bdaf02010-08-31 13:50:42 -0700753 Allocation *a = static_cast<Allocation *>(va);
754 a->subElementData(rsc, x, data, eoff, sizeBytes);
Jason Samsd19f10d2009-05-22 14:03:28 -0700755}
756
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800757void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
Jason Samsd19f10d2009-05-22 14:03:28 -0700758 Allocation *a = static_cast<Allocation *>(va);
Jason Sams49bdaf02010-08-31 13:50:42 -0700759 a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
Jason Samsd19f10d2009-05-22 14:03:28 -0700760}
761
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800762void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
Jason Sams40a29e82009-08-10 14:55:26 -0700763 Allocation *a = static_cast<Allocation *>(va);
764 a->read(data);
765}
766
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800767void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
Jason Sams5edc6082010-10-05 13:32:49 -0700768 Allocation *a = static_cast<Allocation *>(va);
769 a->resize1D(rsc, dimX);
770}
771
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800772void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
Jason Sams5edc6082010-10-05 13:32:49 -0700773 Allocation *a = static_cast<Allocation *>(va);
774 a->resize2D(rsc, dimX, dimY);
775}
776
Alex Sakhartchouk581cc642010-10-27 14:10:07 -0700777#endif //ANDROID_RS_BUILD_FOR_HOST
778
779}
780}
781
Alex Sakhartchouked9f2102010-11-09 17:00:54 -0800782const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
Alex Sakhartchouk80a4c2c2010-07-12 15:50:32 -0700783 Allocation *a = static_cast<Allocation *>(va);
784 a->getType()->incUserRef();
785
786 return a->getType();
787}
788
Jason Sams5476b452010-12-08 16:14:36 -0800789RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
Jason Samsd4b23b52010-12-13 15:32:35 -0800790 RsAllocationMipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800791 uint32_t usages) {
Jason Sams31a7e422010-10-26 13:09:17 -0700792 Context *rsc = static_cast<Context *>(con);
Jason Sams5476b452010-12-08 16:14:36 -0800793 Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages);
Jason Sams31a7e422010-10-26 13:09:17 -0700794 alloc->incUserRef();
795 return alloc;
796}
797
Jason Sams5476b452010-12-08 16:14:36 -0800798
799RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
Jason Samsd4b23b52010-12-13 15:32:35 -0800800 RsAllocationMipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800801 const void *data, uint32_t usages) {
Jason Sams31a7e422010-10-26 13:09:17 -0700802 Context *rsc = static_cast<Context *>(con);
Jason Sams5476b452010-12-08 16:14:36 -0800803 Type *t = static_cast<Type *>(vtype);
Jason Sams31a7e422010-10-26 13:09:17 -0700804
Jason Sams5476b452010-12-08 16:14:36 -0800805 RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
Jason Sams31a7e422010-10-26 13:09:17 -0700806 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
807 if (texAlloc == NULL) {
808 LOGE("Memory allocation failure");
809 return NULL;
810 }
811
Jason Sams5476b452010-12-08 16:14:36 -0800812 memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
Jason Samsd4b23b52010-12-13 15:32:35 -0800813 if (mips == RS_ALLOCATION_MIPMAP_FULL) {
Jason Sams5476b452010-12-08 16:14:36 -0800814 Adapter2D adapt(rsc, texAlloc);
815 Adapter2D adapt2(rsc, texAlloc);
816 for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
817 adapt.setLOD(lod);
818 adapt2.setLOD(lod + 1);
819 mip(adapt2, adapt);
Jason Sams31a7e422010-10-26 13:09:17 -0700820 }
Jason Sams31a7e422010-10-26 13:09:17 -0700821 }
822
Jason Sams5e0035a2010-12-13 17:11:21 -0800823 texAlloc->deferedUploadToTexture(rsc);
Jason Sams31a7e422010-10-26 13:09:17 -0700824 return texAlloc;
825}
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800826
Jason Sams5476b452010-12-08 16:14:36 -0800827RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
Jason Samsd4b23b52010-12-13 15:32:35 -0800828 RsAllocationMipmapControl mips,
Jason Sams5476b452010-12-08 16:14:36 -0800829 const void *data, uint32_t usages) {
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800830 Context *rsc = static_cast<Context *>(con);
Jason Sams5476b452010-12-08 16:14:36 -0800831 Type *t = static_cast<Type *>(vtype);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800832
833 // Cubemap allocation's faces should be Width by Width each.
834 // Source data should have 6 * Width by Width pixels
835 // Error checking is done in the java layer
Jason Sams5476b452010-12-08 16:14:36 -0800836 RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800837 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
838 if (texAlloc == NULL) {
839 LOGE("Memory allocation failure");
840 return NULL;
841 }
842
843 uint8_t *sourcePtr = (uint8_t*)data;
Jason Sams5476b452010-12-08 16:14:36 -0800844 for (uint32_t face = 0; face < 6; face ++) {
845 Adapter2D faceAdapter(rsc, texAlloc);
846 faceAdapter.setFace(face);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800847
Jason Sams5476b452010-12-08 16:14:36 -0800848 size_t cpySize = t->getDimX() * t->getDimX() * t->getElementSizeBytes();
849 memcpy(faceAdapter.getElement(0, 0), sourcePtr, cpySize);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800850
Jason Sams5476b452010-12-08 16:14:36 -0800851 // Move the data pointer to the next cube face
852 sourcePtr += cpySize;
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800853
Jason Samsd4b23b52010-12-13 15:32:35 -0800854 if (mips == RS_ALLOCATION_MIPMAP_FULL) {
Jason Sams5476b452010-12-08 16:14:36 -0800855 Adapter2D adapt(rsc, texAlloc);
856 Adapter2D adapt2(rsc, texAlloc);
857 adapt.setFace(face);
858 adapt2.setFace(face);
859 for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
860 adapt.setLOD(lod);
861 adapt2.setLOD(lod + 1);
862 mip(adapt2, adapt);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800863 }
864 }
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800865 }
866
Jason Sams5e0035a2010-12-13 17:11:21 -0800867 texAlloc->deferedUploadToTexture(rsc);
Alex Sakhartchouk67f2e442010-11-18 15:22:43 -0800868 return texAlloc;
869}