blob: 77e80320b372431183e016070a7fcf393b706922 [file] [log] [blame]
Jason Sams326e0dd2009-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 Sakhartchoukfb6b6142010-05-21 12:53:13 -070016#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Sams326e0dd2009-05-22 14:03:28 -070017#include "rsContext.h"
18
Jason Sams1aa5a4e2009-06-22 17:15:15 -070019#include <GLES/gl.h>
Jason Sams7fabe1a2010-02-23 17:44:28 -080020#include <GLES2/gl2.h>
Jason Sams1aa5a4e2009-06-22 17:15:15 -070021#include <GLES/glext.h>
Alex Sakhartchoukfb6b6142010-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 Sams1aa5a4e2009-06-22 17:15:15 -070028
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -070029#include "utils/StopWatch.h"
30
Jason Sams326e0dd2009-05-22 14:03:28 -070031using namespace android;
32using namespace android::renderscript;
33
Alex Sakhartchouka2aab8b2010-12-15 09:59:58 -080034Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
35 RsAllocationMipmapControl mc)
36 : ObjectBase(rsc) {
Jason Samsfa84da22010-03-01 15:31:04 -080037 init(rsc, type);
38
Jason Sams366c9c82010-12-08 16:14:36 -080039 mUsageFlags = usages;
Alex Sakhartchouka2aab8b2010-12-15 09:59:58 -080040 mMipmapControl = mc;
Jason Sams366c9c82010-12-08 16:14:36 -080041
Jason Samsb89b0b72010-12-13 17:11:21 -080042 allocScriptMemory();
Jason Sams10e5e572010-08-12 12:44:02 -070043 if (mType->getElement()->getHasReferences()) {
44 memset(mPtr, 0, mType->getSizeBytes());
45 }
Jason Samsfa84da22010-03-01 15:31:04 -080046 if (!mPtr) {
47 LOGE("Allocation::Allocation, alloc failure");
48 }
49}
50
Jason Samsfa84da22010-03-01 15:31:04 -080051
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080052void Allocation::init(Context *rsc, const Type *type) {
Jason Sams326e0dd2009-05-22 14:03:28 -070053 mPtr = NULL;
54
55 mCpuWrite = false;
56 mCpuRead = false;
57 mGpuWrite = false;
58 mGpuRead = false;
59
60 mReadWriteRatio = 0;
61 mUpdateSize = 0;
Jason Samsebc50192010-12-13 15:32:35 -080062 mUsageFlags = 0;
63 mMipmapControl = RS_ALLOCATION_MIPMAP_NONE;
Jason Sams326e0dd2009-05-22 14:03:28 -070064
Jason Sams326e0dd2009-05-22 14:03:28 -070065 mTextureID = 0;
Jason Sams326e0dd2009-05-22 14:03:28 -070066 mBufferID = 0;
Jason Samscf4c7c92009-12-14 12:57:40 -080067 mUploadDefered = false;
Jason Sams326e0dd2009-05-22 14:03:28 -070068
Jason Samsfa84da22010-03-01 15:31:04 -080069 mUserBitmapCallback = NULL;
70 mUserBitmapCallbackData = NULL;
71
Jason Sams326e0dd2009-05-22 14:03:28 -070072 mType.set(type);
Jason Samse5ffb872009-08-09 17:01:55 -070073 rsAssert(type);
Jason Samsfa84da22010-03-01 15:31:04 -080074
75 mPtr = NULL;
Jason Sams326e0dd2009-05-22 14:03:28 -070076}
77
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080078Allocation::~Allocation() {
Jason Samsfa84da22010-03-01 15:31:04 -080079 if (mUserBitmapCallback != NULL) {
80 mUserBitmapCallback(mUserBitmapCallbackData);
Jason Samsb89b0b72010-12-13 17:11:21 -080081 mPtr = NULL;
Jason Samsfa84da22010-03-01 15:31:04 -080082 }
Jason Samsb89b0b72010-12-13 17:11:21 -080083 freeScriptMemory();
Jason Samse402ed32009-11-03 11:25:42 -080084
85 if (mBufferID) {
86 // Causes a SW crash....
87 //LOGV(" mBufferID %i", mBufferID);
88 //glDeleteBuffers(1, &mBufferID);
89 //mBufferID = 0;
90 }
91 if (mTextureID) {
92 glDeleteTextures(1, &mTextureID);
93 mTextureID = 0;
94 }
Jason Sams326e0dd2009-05-22 14:03:28 -070095}
96
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080097void Allocation::setCpuWritable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -070098}
99
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800100void Allocation::setGpuWritable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700101}
102
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800103void Allocation::setCpuReadable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700104}
105
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800106void Allocation::setGpuReadable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700107}
108
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800109bool Allocation::fixAllocation() {
Jason Sams326e0dd2009-05-22 14:03:28 -0700110 return false;
111}
112
Jason Samsb89b0b72010-12-13 17:11:21 -0800113void Allocation::deferedUploadToTexture(const Context *rsc) {
Jason Samsebc50192010-12-13 15:32:35 -0800114 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
Jason Samscf4c7c92009-12-14 12:57:40 -0800115 mUploadDefered = true;
116}
117
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800118uint32_t Allocation::getGLTarget() const {
Jason Samsebc50192010-12-13 15:32:35 -0800119 if (getIsTexture()) {
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800120 if (mType->getDimFaces()) {
121 return GL_TEXTURE_CUBE_MAP;
122 } else {
123 return GL_TEXTURE_2D;
124 }
125 }
Jason Samsebc50192010-12-13 15:32:35 -0800126 if (getIsBufferObject()) {
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800127 return GL_ARRAY_BUFFER;
128 }
129 return 0;
130}
131
Jason Samsb89b0b72010-12-13 17:11:21 -0800132void Allocation::allocScriptMemory() {
133 rsAssert(!mPtr);
134 mPtr = malloc(mType->getSizeBytes());
135}
136
137void Allocation::freeScriptMemory() {
138 rsAssert(!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT));
139 if (mPtr) {
140 free(mPtr);
141 mPtr = NULL;
142 }
143}
144
145
Jason Sams366c9c82010-12-08 16:14:36 -0800146void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
147 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
148
Jason Samsebc50192010-12-13 15:32:35 -0800149 if (getIsTexture()) {
Jason Sams366c9c82010-12-08 16:14:36 -0800150 uploadToTexture(rsc);
151 }
Jason Samsebc50192010-12-13 15:32:35 -0800152 if (getIsBufferObject()) {
Jason Sams366c9c82010-12-08 16:14:36 -0800153 uploadToBufferObject(rsc);
154 }
155
156 mUploadDefered = false;
157}
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800158
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800159void Allocation::uploadToTexture(const Context *rsc) {
Jason Samscf4c7c92009-12-14 12:57:40 -0800160
Jason Samsebc50192010-12-13 15:32:35 -0800161 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
Jason Samsd01d9702009-12-23 14:35:29 -0800162 GLenum type = mType->getElement()->getComponent().getGLType();
163 GLenum format = mType->getElement()->getComponent().getGLFormat();
Jason Sams565ac362009-06-03 16:04:54 -0700164
165 if (!type || !format) {
166 return;
167 }
168
Jason Samsb89b0b72010-12-13 17:11:21 -0800169 if (!mPtr) {
170 return;
171 }
172
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700173 bool isFirstUpload = false;
174
Jason Sams326e0dd2009-05-22 14:03:28 -0700175 if (!mTextureID) {
176 glGenTextures(1, &mTextureID);
Jason Sams13e26342009-11-24 12:26:35 -0800177
178 if (!mTextureID) {
179 // This should not happen, however, its likely the cause of the
180 // white sqare bug.
181 // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
182 LOGE("Upload to texture failed to gen mTextureID");
183 rsc->dumpDebug();
Jason Samscf4c7c92009-12-14 12:57:40 -0800184 mUploadDefered = true;
185 return;
Jason Sams13e26342009-11-24 12:26:35 -0800186 }
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700187 isFirstUpload = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700188 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800189
190 GLenum target = (GLenum)getGLTarget();
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800191 if (target == GL_TEXTURE_2D) {
Jason Samsb89b0b72010-12-13 17:11:21 -0800192 upload2DTexture(isFirstUpload, mPtr);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800193 } else if (target == GL_TEXTURE_CUBE_MAP) {
194 uploadCubeTexture(isFirstUpload);
195 }
196
Jason Samsb89b0b72010-12-13 17:11:21 -0800197 if (!(mUsageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
198 freeScriptMemory();
199 }
200
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800201 rsc->checkError("Allocation::uploadToTexture");
202}
203
Jason Samsb89b0b72010-12-13 17:11:21 -0800204void Allocation::upload2DTexture(bool isFirstUpload, const void *ptr) {
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800205 GLenum type = mType->getElement()->getComponent().getGLType();
206 GLenum format = mType->getElement()->getComponent().getGLFormat();
207
Jason Samsb89b0b72010-12-13 17:11:21 -0800208 GLenum target = (GLenum)getGLTarget();
209 glBindTexture(target, mTextureID);
210 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Jason Sams326e0dd2009-05-22 14:03:28 -0700211
Jason Samsb89b0b72010-12-13 17:11:21 -0800212 for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
213 const uint8_t *p = (const uint8_t *)ptr;
214 p += mType->getLODOffset(lod);
215
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800216 if (isFirstUpload) {
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700217 glTexImage2D(GL_TEXTURE_2D, lod, format,
Jason Samsb89b0b72010-12-13 17:11:21 -0800218 mType->getLODDimX(lod), mType->getLODDimY(lod),
219 0, format, type, p);
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700220 } else {
221 glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
Jason Samsb89b0b72010-12-13 17:11:21 -0800222 mType->getLODDimX(lod), mType->getLODDimY(lod),
223 format, type, p);
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700224 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700225 }
Jason Samsb7e83bd2010-12-15 01:41:00 -0800226
227 if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
228#ifndef ANDROID_RS_BUILD_FOR_HOST
229 glGenerateMipmap(target);
230#endif //ANDROID_RS_BUILD_FOR_HOST
231 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800232}
Jason Sams7fabe1a2010-02-23 17:44:28 -0800233
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800234void Allocation::uploadCubeTexture(bool isFirstUpload) {
235 GLenum type = mType->getElement()->getComponent().getGLType();
236 GLenum format = mType->getElement()->getComponent().getGLFormat();
237
Jason Samsb89b0b72010-12-13 17:11:21 -0800238 GLenum target = (GLenum)getGLTarget();
239 glBindTexture(target, mTextureID);
240 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
241
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800242 GLenum faceOrder[] = {
243 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
244 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
245 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
246 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
247 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
248 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
249 };
250
251 Adapter2D adapt(getContext(), this);
252 for (uint32_t face = 0; face < 6; face ++) {
253 adapt.setFace(face);
254
Jason Samsb89b0b72010-12-13 17:11:21 -0800255 for (uint32_t lod = 0; lod < mType->getLODCount(); lod++) {
256 adapt.setLOD(lod);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800257
258 uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
259
260 if (isFirstUpload) {
261 glTexImage2D(faceOrder[face], lod, format,
262 adapt.getDimX(), adapt.getDimY(),
263 0, format, type, ptr);
264 } else {
265 glTexSubImage2D(faceOrder[face], lod, 0, 0,
266 adapt.getDimX(), adapt.getDimY(),
267 format, type, ptr);
268 }
269 }
270 }
Jason Samsb7e83bd2010-12-15 01:41:00 -0800271
272 if (mMipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
273#ifndef ANDROID_RS_BUILD_FOR_HOST
274 glGenerateMipmap(target);
275#endif //ANDROID_RS_BUILD_FOR_HOST
276 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700277}
278
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800279void Allocation::deferedUploadToBufferObject(const Context *rsc) {
Jason Samsebc50192010-12-13 15:32:35 -0800280 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
Jason Samscf4c7c92009-12-14 12:57:40 -0800281 mUploadDefered = true;
282}
283
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800284void Allocation::uploadToBufferObject(const Context *rsc) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700285 rsAssert(!mType->getDimY());
286 rsAssert(!mType->getDimZ());
287
Jason Samsebc50192010-12-13 15:32:35 -0800288 mUsageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
Jason Samscf4c7c92009-12-14 12:57:40 -0800289
Jason Sams326e0dd2009-05-22 14:03:28 -0700290 if (!mBufferID) {
291 glGenBuffers(1, &mBufferID);
292 }
Jason Samscf4c7c92009-12-14 12:57:40 -0800293 if (!mBufferID) {
294 LOGE("Upload to buffer object failed");
295 mUploadDefered = true;
296 return;
297 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800298 GLenum target = (GLenum)getGLTarget();
299 glBindBuffer(target, mBufferID);
300 glBufferData(target, mType->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
301 glBindBuffer(target, 0);
Jason Samsc1ed5892010-03-10 17:30:41 -0800302 rsc->checkError("Allocation::uploadToBufferObject");
Jason Sams326e0dd2009-05-22 14:03:28 -0700303}
304
Jason Sams366c9c82010-12-08 16:14:36 -0800305void Allocation::uploadCheck(Context *rsc) {
Jason Samscf4c7c92009-12-14 12:57:40 -0800306 if (mUploadDefered) {
Jason Sams366c9c82010-12-08 16:14:36 -0800307 syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
Jason Samscf4c7c92009-12-14 12:57:40 -0800308 }
309}
310
Jason Samse5ffb872009-08-09 17:01:55 -0700311
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800312void Allocation::data(Context *rsc, const void *data, uint32_t sizeBytes) {
Jason Sams9397e302009-08-27 20:23:34 -0700313 uint32_t size = mType->getSizeBytes();
314 if (size != sizeBytes) {
315 LOGE("Allocation::data called with mismatched size expected %i, got %i", size, sizeBytes);
316 return;
317 }
Jason Samse3929c92010-08-09 18:13:33 -0700318
319 if (mType->getElement()->getHasReferences()) {
320 incRefs(data, sizeBytes / mType->getElement()->getSizeBytes());
321 decRefs(mPtr, sizeBytes / mType->getElement()->getSizeBytes());
322 }
323
Jason Sams9397e302009-08-27 20:23:34 -0700324 memcpy(mPtr, data, size);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700325 sendDirty();
Jason Samscf4c7c92009-12-14 12:57:40 -0800326 mUploadDefered = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700327}
328
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800329void Allocation::read(void *data) {
Jason Samse579df42009-08-10 14:55:26 -0700330 memcpy(data, mPtr, mType->getSizeBytes());
331}
332
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800333void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700334 uint32_t eSize = mType->getElementSizeBytes();
335 uint8_t * ptr = static_cast<uint8_t *>(mPtr);
336 ptr += eSize * xoff;
Jason Sams9397e302009-08-27 20:23:34 -0700337 uint32_t size = count * eSize;
338
339 if (size != sizeBytes) {
340 LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
Jason Samse12c1c52009-09-27 17:50:38 -0700341 mType->dumpLOGV("type info");
Jason Sams9397e302009-08-27 20:23:34 -0700342 return;
343 }
Jason Samse3929c92010-08-09 18:13:33 -0700344
345 if (mType->getElement()->getHasReferences()) {
346 incRefs(data, count);
347 decRefs(ptr, count);
348 }
349
Jason Sams9397e302009-08-27 20:23:34 -0700350 memcpy(ptr, data, size);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700351 sendDirty();
Jason Samscf4c7c92009-12-14 12:57:40 -0800352 mUploadDefered = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700353}
354
Jason Sams5f0c84c2010-08-31 13:50:42 -0700355void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800356 uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700357 uint32_t eSize = mType->getElementSizeBytes();
358 uint32_t lineSize = eSize * w;
359 uint32_t destW = mType->getDimX();
360
361 const uint8_t *src = static_cast<const uint8_t *>(data);
362 uint8_t *dst = static_cast<uint8_t *>(mPtr);
363 dst += eSize * (xoff + yoff * destW);
Jason Sams9397e302009-08-27 20:23:34 -0700364
365 if ((lineSize * eSize * h) != sizeBytes) {
366 rsAssert(!"Allocation::subData called with mismatched size");
367 return;
368 }
369
Jason Sams326e0dd2009-05-22 14:03:28 -0700370 for (uint32_t line=yoff; line < (yoff+h); line++) {
Jason Samse3929c92010-08-09 18:13:33 -0700371 if (mType->getElement()->getHasReferences()) {
372 incRefs(src, w);
373 decRefs(dst, w);
374 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700375 memcpy(dst, src, lineSize);
376 src += lineSize;
377 dst += destW * eSize;
378 }
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700379 sendDirty();
Jason Samscf4c7c92009-12-14 12:57:40 -0800380 mUploadDefered = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700381}
382
Jason Sams5f0c84c2010-08-31 13:50:42 -0700383void Allocation::subData(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800384 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700385}
386
Jason Sams5f0c84c2010-08-31 13:50:42 -0700387void Allocation::subElementData(Context *rsc, uint32_t x, const void *data,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800388 uint32_t cIdx, uint32_t sizeBytes) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700389 uint32_t eSize = mType->getElementSizeBytes();
390 uint8_t * ptr = static_cast<uint8_t *>(mPtr);
391 ptr += eSize * x;
392
393 if (cIdx >= mType->getElement()->getFieldCount()) {
394 LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
395 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
396 return;
397 }
398
399 if (x >= mType->getDimX()) {
400 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
401 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
402 return;
403 }
404
405 const Element * e = mType->getElement()->getField(cIdx);
406 ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
407
408 if (sizeBytes != e->getSizeBytes()) {
409 LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
410 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
411 return;
412 }
413
414 if (e->getHasReferences()) {
415 e->incRefs(data);
416 e->decRefs(ptr);
417 }
418
419 memcpy(ptr, data, sizeBytes);
420 sendDirty();
421 mUploadDefered = true;
422}
423
424void Allocation::subElementData(Context *rsc, uint32_t x, uint32_t y,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800425 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700426 uint32_t eSize = mType->getElementSizeBytes();
427 uint8_t * ptr = static_cast<uint8_t *>(mPtr);
428 ptr += eSize * (x + y * mType->getDimX());
429
430 if (x >= mType->getDimX()) {
431 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
432 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
433 return;
434 }
435
436 if (y >= mType->getDimY()) {
437 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
438 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
439 return;
440 }
441
442 if (cIdx >= mType->getElement()->getFieldCount()) {
443 LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
444 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
445 return;
446 }
447
448 const Element * e = mType->getElement()->getField(cIdx);
449 ptr += mType->getElement()->getFieldOffsetBytes(cIdx);
450
451 if (sizeBytes != e->getSizeBytes()) {
452 LOGE("Error Allocation::subElementData data size %i does not match field size %i.", sizeBytes, e->getSizeBytes());
453 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
454 return;
455 }
456
457 if (e->getHasReferences()) {
458 e->incRefs(data);
459 e->decRefs(ptr);
460 }
461
462 memcpy(ptr, data, sizeBytes);
463 sendDirty();
464 mUploadDefered = true;
465}
466
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800467void Allocation::addProgramToDirty(const Program *p) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700468 mToDirtyList.push(p);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700469}
Jason Sams326e0dd2009-05-22 14:03:28 -0700470
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800471void Allocation::removeProgramToDirty(const Program *p) {
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700472 for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
473 if (mToDirtyList[ct] == p) {
474 mToDirtyList.removeAt(ct);
475 return;
476 }
477 }
478 rsAssert(0);
479}
480
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800481void Allocation::dumpLOGV(const char *prefix) const {
Jason Samsc21cf402009-11-17 17:26:46 -0800482 ObjectBase::dumpLOGV(prefix);
483
484 String8 s(prefix);
485 s.append(" type ");
486 if (mType.get()) {
487 mType->dumpLOGV(s.string());
488 }
489
490 LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
491 prefix, mPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
492
Jason Samsebc50192010-12-13 15:32:35 -0800493 LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
494 prefix, mUsageFlags, mMipmapControl, mTextureID, mBufferID);
Jason Samsc21cf402009-11-17 17:26:46 -0800495}
Jason Sams326e0dd2009-05-22 14:03:28 -0700496
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800497void Allocation::serialize(OStream *stream) const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700498 // Need to identify ourselves
499 stream->addU32((uint32_t)getClassId());
500
501 String8 name(getName());
502 stream->addString(&name);
503
504 // First thing we need to serialize is the type object since it will be needed
505 // to initialize the class
506 mType->serialize(stream);
507
508 uint32_t dataSize = mType->getSizeBytes();
509 // Write how much data we are storing
510 stream->addU32(dataSize);
511 // Now write the data
512 stream->addByteArray(mPtr, dataSize);
513}
514
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800515Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700516 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700517 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800518 if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700519 LOGE("allocation loading skipped due to invalid class id\n");
520 return NULL;
521 }
522
523 String8 name;
524 stream->loadString(&name);
525
526 Type *type = Type::createFromStream(rsc, stream);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800527 if (!type) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700528 return NULL;
529 }
530 type->compute();
531
532 // Number of bytes we wrote out for this allocation
533 uint32_t dataSize = stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800534 if (dataSize != type->getSizeBytes()) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700535 LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
Jason Sams225afd32010-10-21 14:06:55 -0700536 ObjectBase::checkDelete(type);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700537 return NULL;
538 }
539
Jason Samsebc50192010-12-13 15:32:35 -0800540 Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700541 alloc->setName(name.string(), name.size());
542
543 // Read in all of our allocation data
Jason Sams5f0c84c2010-08-31 13:50:42 -0700544 alloc->data(rsc, stream->getPtr() + stream->getPos(), dataSize);
Alex Sakhartchouke6d9fbc2010-08-11 10:30:44 -0700545 stream->reset(stream->getPos() + dataSize);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700546
547 return alloc;
548}
549
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800550void Allocation::sendDirty() const {
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700551 for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
552 mToDirtyList[ct]->forceDirty();
553 }
554}
Jason Sams326e0dd2009-05-22 14:03:28 -0700555
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800556void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
Jason Samse3929c92010-08-09 18:13:33 -0700557 const uint8_t *p = static_cast<const uint8_t *>(ptr);
558 const Element *e = mType->getElement();
559 uint32_t stride = e->getSizeBytes();
560
Jason Sams96abf812010-10-05 13:32:49 -0700561 p += stride * startOff;
Jason Samse3929c92010-08-09 18:13:33 -0700562 while (ct > 0) {
563 e->incRefs(p);
564 ct --;
565 p += stride;
566 }
567}
568
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800569void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
Jason Samse3929c92010-08-09 18:13:33 -0700570 const uint8_t *p = static_cast<const uint8_t *>(ptr);
571 const Element *e = mType->getElement();
572 uint32_t stride = e->getSizeBytes();
573
Jason Sams96abf812010-10-05 13:32:49 -0700574 p += stride * startOff;
Jason Samse3929c92010-08-09 18:13:33 -0700575 while (ct > 0) {
576 e->decRefs(p);
577 ct --;
578 p += stride;
579 }
580}
581
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800582void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
Jason Sams96abf812010-10-05 13:32:49 -0700583}
584
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800585void Allocation::resize1D(Context *rsc, uint32_t dimX) {
Jason Sams96abf812010-10-05 13:32:49 -0700586 Type *t = mType->cloneAndResize1D(rsc, dimX);
587
588 uint32_t oldDimX = mType->getDimX();
589 if (dimX == oldDimX) {
590 return;
591 }
592
593 if (dimX < oldDimX) {
594 decRefs(mPtr, oldDimX - dimX, dimX);
595 }
596 mPtr = realloc(mPtr, t->getSizeBytes());
597
598 if (dimX > oldDimX) {
599 const Element *e = mType->getElement();
600 uint32_t stride = e->getSizeBytes();
601 memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
602 }
603 mType.set(t);
604}
605
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800606void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
Jason Sams96abf812010-10-05 13:32:49 -0700607 LOGE("not implemented");
608}
609
Jason Sams326e0dd2009-05-22 14:03:28 -0700610/////////////////
Jason Sams565ac362009-06-03 16:04:54 -0700611//
Jason Sams326e0dd2009-05-22 14:03:28 -0700612
613
614namespace android {
615namespace renderscript {
616
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800617void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700618 Allocation *alloc = static_cast<Allocation *>(va);
Jason Samsb89b0b72010-12-13 17:11:21 -0800619 alloc->deferedUploadToTexture(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -0700620}
621
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800622void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700623 Allocation *alloc = static_cast<Allocation *>(va);
Jason Samscf4c7c92009-12-14 12:57:40 -0800624 alloc->deferedUploadToBufferObject(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -0700625}
626
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800627static void mip565(const Adapter2D &out, const Adapter2D &in) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700628 uint32_t w = out.getDimX();
629 uint32_t h = out.getDimY();
630
Jason Samse9f5c532009-07-28 17:20:11 -0700631 for (uint32_t y=0; y < h; y++) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700632 uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
633 const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
634 const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
635
Jason Samse9f5c532009-07-28 17:20:11 -0700636 for (uint32_t x=0; x < w; x++) {
Jason Sams565ac362009-06-03 16:04:54 -0700637 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
638 oPtr ++;
639 i1 += 2;
640 i2 += 2;
641 }
642 }
643}
644
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800645static void mip8888(const Adapter2D &out, const Adapter2D &in) {
Jason Sams565ac362009-06-03 16:04:54 -0700646 uint32_t w = out.getDimX();
647 uint32_t h = out.getDimY();
648
Jason Samse9f5c532009-07-28 17:20:11 -0700649 for (uint32_t y=0; y < h; y++) {
Jason Sams565ac362009-06-03 16:04:54 -0700650 uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
651 const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
652 const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
653
Jason Samse9f5c532009-07-28 17:20:11 -0700654 for (uint32_t x=0; x < w; x++) {
Jason Sams565ac362009-06-03 16:04:54 -0700655 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
Jason Sams326e0dd2009-05-22 14:03:28 -0700656 oPtr ++;
657 i1 += 2;
658 i2 += 2;
659 }
660 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700661}
662
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800663static void mip8(const Adapter2D &out, const Adapter2D &in) {
Jason Sams2f6d8612010-01-19 17:53:54 -0800664 uint32_t w = out.getDimX();
665 uint32_t h = out.getDimY();
666
667 for (uint32_t y=0; y < h; y++) {
668 uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
669 const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
670 const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
671
672 for (uint32_t x=0; x < w; x++) {
673 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
674 oPtr ++;
675 i1 += 2;
676 i2 += 2;
677 }
678 }
679}
680
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800681static void mip(const Adapter2D &out, const Adapter2D &in) {
682 switch (out.getBaseType()->getElement()->getSizeBits()) {
Jason Samse9f5c532009-07-28 17:20:11 -0700683 case 32:
684 mip8888(out, in);
685 break;
686 case 16:
687 mip565(out, in);
688 break;
Jason Sams2f6d8612010-01-19 17:53:54 -0800689 case 8:
690 mip8(out, in);
691 break;
Jason Samse9f5c532009-07-28 17:20:11 -0700692 }
Jason Samse9f5c532009-07-28 17:20:11 -0700693}
Jason Sams326e0dd2009-05-22 14:03:28 -0700694
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700695#ifndef ANDROID_RS_BUILD_FOR_HOST
696
Jason Sams366c9c82010-12-08 16:14:36 -0800697void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
698 Allocation *a = static_cast<Allocation *>(va);
699 a->syncAll(rsc, src);
700}
701
Jason Sams837e3882010-12-10 16:03:15 -0800702void rsi_AllocationCopyFromBitmap(Context *rsc, RsAllocation va, const void *data, size_t dataLen) {
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700703 Allocation *texAlloc = static_cast<Allocation *>(va);
Jason Sams837e3882010-12-10 16:03:15 -0800704 const Type * t = texAlloc->getType();
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700705
Jason Sams837e3882010-12-10 16:03:15 -0800706 uint32_t w = t->getDimX();
707 uint32_t h = t->getDimY();
708 bool genMips = t->getDimLOD();
709 size_t s = w * h * t->getElementSizeBytes();
710 if (s != dataLen) {
711 rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
712 return;
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700713 }
Jason Sams837e3882010-12-10 16:03:15 -0800714
Jason Samsb89b0b72010-12-13 17:11:21 -0800715 if (texAlloc->getIsScript()) {
716 memcpy(texAlloc->getPtr(), data, s);
717 if (genMips) {
718 Adapter2D adapt(rsc, texAlloc);
719 Adapter2D adapt2(rsc, texAlloc);
720 for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
721 adapt.setLOD(lod);
722 adapt2.setLOD(lod + 1);
723 mip(adapt2, adapt);
724 }
Jason Sams837e3882010-12-10 16:03:15 -0800725 }
Jason Samsb89b0b72010-12-13 17:11:21 -0800726 } else {
727 texAlloc->upload2DTexture(false, data);
Jason Sams837e3882010-12-10 16:03:15 -0800728 }
Jason Samsb89b0b72010-12-13 17:11:21 -0800729
Jason Sams837e3882010-12-10 16:03:15 -0800730}
731
732void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
733 Allocation *texAlloc = static_cast<Allocation *>(va);
734 const Type * t = texAlloc->getType();
735
736 size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
737 if (s != dataLen) {
738 rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
739 return;
740 }
741
742 memcpy(data, texAlloc->getPtr(), s);
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700743}
744
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800745void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700746 Allocation *a = static_cast<Allocation *>(va);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700747 a->data(rsc, data, sizeBytes);
Jason Sams326e0dd2009-05-22 14:03:28 -0700748}
749
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800750void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700751 Allocation *a = static_cast<Allocation *>(va);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700752 a->subData(rsc, xoff, count, data, sizeBytes);
753}
754
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800755void rsi_Allocation2DSubElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, const void *data, uint32_t eoff, uint32_t sizeBytes) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700756 Allocation *a = static_cast<Allocation *>(va);
757 a->subElementData(rsc, x, y, data, eoff, sizeBytes);
758}
759
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800760void rsi_Allocation1DSubElementData(Context *rsc, RsAllocation va, uint32_t x, const void *data, uint32_t eoff, uint32_t sizeBytes) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700761 Allocation *a = static_cast<Allocation *>(va);
762 a->subElementData(rsc, x, data, eoff, sizeBytes);
Jason Sams326e0dd2009-05-22 14:03:28 -0700763}
764
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800765void 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 Sams326e0dd2009-05-22 14:03:28 -0700766 Allocation *a = static_cast<Allocation *>(va);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700767 a->subData(rsc, xoff, yoff, w, h, data, sizeBytes);
Jason Sams326e0dd2009-05-22 14:03:28 -0700768}
769
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800770void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data) {
Jason Samse579df42009-08-10 14:55:26 -0700771 Allocation *a = static_cast<Allocation *>(va);
772 a->read(data);
773}
774
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800775void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
Jason Sams96abf812010-10-05 13:32:49 -0700776 Allocation *a = static_cast<Allocation *>(va);
777 a->resize1D(rsc, dimX);
778}
779
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800780void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
Jason Sams96abf812010-10-05 13:32:49 -0700781 Allocation *a = static_cast<Allocation *>(va);
782 a->resize2D(rsc, dimX, dimY);
783}
784
Alex Sakhartchoukdc763f32010-10-27 14:10:07 -0700785#endif //ANDROID_RS_BUILD_FOR_HOST
786
787}
788}
789
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800790const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
Alex Sakhartchoukd18c7442010-07-12 15:50:32 -0700791 Allocation *a = static_cast<Allocation *>(va);
792 a->getType()->incUserRef();
793
794 return a->getType();
795}
796
Jason Sams366c9c82010-12-08 16:14:36 -0800797RsAllocation rsaAllocationCreateTyped(RsContext con, RsType vtype,
Jason Samsebc50192010-12-13 15:32:35 -0800798 RsAllocationMipmapControl mips,
Jason Sams366c9c82010-12-08 16:14:36 -0800799 uint32_t usages) {
Jason Samsf0c1df42010-10-26 13:09:17 -0700800 Context *rsc = static_cast<Context *>(con);
Alex Sakhartchouka2aab8b2010-12-15 09:59:58 -0800801 Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
Jason Samsf0c1df42010-10-26 13:09:17 -0700802 alloc->incUserRef();
803 return alloc;
804}
805
Jason Sams366c9c82010-12-08 16:14:36 -0800806
807RsAllocation rsaAllocationCreateFromBitmap(RsContext con, RsType vtype,
Jason Samsebc50192010-12-13 15:32:35 -0800808 RsAllocationMipmapControl mips,
Jason Sams366c9c82010-12-08 16:14:36 -0800809 const void *data, uint32_t usages) {
Jason Samsf0c1df42010-10-26 13:09:17 -0700810 Context *rsc = static_cast<Context *>(con);
Jason Sams366c9c82010-12-08 16:14:36 -0800811 Type *t = static_cast<Type *>(vtype);
Jason Samsf0c1df42010-10-26 13:09:17 -0700812
Jason Sams366c9c82010-12-08 16:14:36 -0800813 RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, vtype, mips, usages);
Jason Samsf0c1df42010-10-26 13:09:17 -0700814 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
815 if (texAlloc == NULL) {
816 LOGE("Memory allocation failure");
817 return NULL;
818 }
819
Jason Sams366c9c82010-12-08 16:14:36 -0800820 memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
Jason Samsebc50192010-12-13 15:32:35 -0800821 if (mips == RS_ALLOCATION_MIPMAP_FULL) {
Jason Sams366c9c82010-12-08 16:14:36 -0800822 Adapter2D adapt(rsc, texAlloc);
823 Adapter2D adapt2(rsc, texAlloc);
824 for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
825 adapt.setLOD(lod);
826 adapt2.setLOD(lod + 1);
827 mip(adapt2, adapt);
Jason Samsf0c1df42010-10-26 13:09:17 -0700828 }
Jason Samsf0c1df42010-10-26 13:09:17 -0700829 }
830
Jason Samsb89b0b72010-12-13 17:11:21 -0800831 texAlloc->deferedUploadToTexture(rsc);
Jason Samsf0c1df42010-10-26 13:09:17 -0700832 return texAlloc;
833}
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800834
Jason Sams366c9c82010-12-08 16:14:36 -0800835RsAllocation rsaAllocationCubeCreateFromBitmap(RsContext con, RsType vtype,
Jason Samsebc50192010-12-13 15:32:35 -0800836 RsAllocationMipmapControl mips,
Jason Sams366c9c82010-12-08 16:14:36 -0800837 const void *data, uint32_t usages) {
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800838 Context *rsc = static_cast<Context *>(con);
Jason Sams366c9c82010-12-08 16:14:36 -0800839 Type *t = static_cast<Type *>(vtype);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800840
841 // Cubemap allocation's faces should be Width by Width each.
842 // Source data should have 6 * Width by Width pixels
843 // Error checking is done in the java layer
Jason Sams366c9c82010-12-08 16:14:36 -0800844 RsAllocation vTexAlloc = rsaAllocationCreateTyped(rsc, t, mips, usages);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800845 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
846 if (texAlloc == NULL) {
847 LOGE("Memory allocation failure");
848 return NULL;
849 }
850
851 uint8_t *sourcePtr = (uint8_t*)data;
Jason Sams366c9c82010-12-08 16:14:36 -0800852 for (uint32_t face = 0; face < 6; face ++) {
853 Adapter2D faceAdapter(rsc, texAlloc);
854 faceAdapter.setFace(face);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800855
Jason Sams366c9c82010-12-08 16:14:36 -0800856 size_t cpySize = t->getDimX() * t->getDimX() * t->getElementSizeBytes();
857 memcpy(faceAdapter.getElement(0, 0), sourcePtr, cpySize);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800858
Jason Sams366c9c82010-12-08 16:14:36 -0800859 // Move the data pointer to the next cube face
860 sourcePtr += cpySize;
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800861
Jason Samsebc50192010-12-13 15:32:35 -0800862 if (mips == RS_ALLOCATION_MIPMAP_FULL) {
Jason Sams366c9c82010-12-08 16:14:36 -0800863 Adapter2D adapt(rsc, texAlloc);
864 Adapter2D adapt2(rsc, texAlloc);
865 adapt.setFace(face);
866 adapt2.setFace(face);
867 for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
868 adapt.setLOD(lod);
869 adapt2.setLOD(lod + 1);
870 mip(adapt2, adapt);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800871 }
872 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800873 }
874
Jason Samsb89b0b72010-12-13 17:11:21 -0800875 texAlloc->deferedUploadToTexture(rsc);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800876 return texAlloc;
877}