blob: b5f6f5608bcf59c7e104a8172773026a9eff8273 [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 */
Jason Sams326e0dd2009-05-22 14:03:28 -070016
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -080017#include "rsContext.h"
18#ifndef ANDROID_RS_SERIALIZE
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 Sakhartchouk77d9f4b2011-01-31 14:53:24 -080022#endif //ANDROID_RS_SERIALIZE
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -070023
Jason Sams326e0dd2009-05-22 14:03:28 -070024using namespace android;
25using namespace android::renderscript;
26
Alex Sakhartchouka2aab8b2010-12-15 09:59:58 -080027Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
28 RsAllocationMipmapControl mc)
29 : ObjectBase(rsc) {
Jason Samsfa84da22010-03-01 15:31:04 -080030 init(rsc, type);
31
Jason Samsbad80742011-03-16 16:29:28 -070032 mHal.state.usageFlags = usages;
33 mHal.state.mipmapControl = mc;
Jason Sams366c9c82010-12-08 16:14:36 -080034
Jason Samsb89b0b72010-12-13 17:11:21 -080035 allocScriptMemory();
Jason Samsbad80742011-03-16 16:29:28 -070036 if (mHal.state.type->getElement()->getHasReferences()) {
37 memset(mHal.state.mallocPtr, 0, mHal.state.type->getSizeBytes());
Jason Sams10e5e572010-08-12 12:44:02 -070038 }
Jason Samsbad80742011-03-16 16:29:28 -070039 if (!mHal.state.mallocPtr) {
Jason Samsfa84da22010-03-01 15:31:04 -080040 LOGE("Allocation::Allocation, alloc failure");
41 }
42}
43
Jason Samsfa84da22010-03-01 15:31:04 -080044
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080045void Allocation::init(Context *rsc, const Type *type) {
Jason Samsbad80742011-03-16 16:29:28 -070046 memset(&mHal, 0, sizeof(mHal));
47 mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
Jason Sams326e0dd2009-05-22 14:03:28 -070048
49 mCpuWrite = false;
50 mCpuRead = false;
51 mGpuWrite = false;
52 mGpuRead = false;
53
54 mReadWriteRatio = 0;
55 mUpdateSize = 0;
56
Jason Sams326e0dd2009-05-22 14:03:28 -070057 mTextureID = 0;
Jason Sams326e0dd2009-05-22 14:03:28 -070058 mBufferID = 0;
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -070059 mRenderTargetID = 0;
60 mUploadDeferred = false;
Jason Sams326e0dd2009-05-22 14:03:28 -070061
Jason Samsfa84da22010-03-01 15:31:04 -080062 mUserBitmapCallback = NULL;
63 mUserBitmapCallbackData = NULL;
64
Jason Samsbad80742011-03-16 16:29:28 -070065 mHal.state.type.set(type);
66 updateCache();
67}
Jason Samsfa84da22010-03-01 15:31:04 -080068
Jason Samsbad80742011-03-16 16:29:28 -070069void Allocation::updateCache() {
70 const Type *type = mHal.state.type.get();
71 mHal.state.dimensionX = type->getDimX();
72 mHal.state.dimensionY = type->getDimY();
73 mHal.state.dimensionZ = type->getDimZ();
74 mHal.state.hasFaces = type->getDimFaces();
75 mHal.state.hasMipmaps = type->getDimLOD();
76 mHal.state.elementSizeBytes = type->getElementSizeBytes();
77 mHal.state.hasReferences = mHal.state.type->getElement()->getHasReferences();
Jason Sams326e0dd2009-05-22 14:03:28 -070078}
79
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -080080Allocation::~Allocation() {
Jason Samsfa84da22010-03-01 15:31:04 -080081 if (mUserBitmapCallback != NULL) {
82 mUserBitmapCallback(mUserBitmapCallbackData);
Jason Samsbad80742011-03-16 16:29:28 -070083 mHal.state.mallocPtr = NULL;
Jason Samsfa84da22010-03-01 15:31:04 -080084 }
Jason Samsb89b0b72010-12-13 17:11:21 -080085 freeScriptMemory();
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -080086#ifndef ANDROID_RS_SERIALIZE
Jason Samse402ed32009-11-03 11:25:42 -080087 if (mBufferID) {
88 // Causes a SW crash....
89 //LOGV(" mBufferID %i", mBufferID);
90 //glDeleteBuffers(1, &mBufferID);
91 //mBufferID = 0;
92 }
93 if (mTextureID) {
94 glDeleteTextures(1, &mTextureID);
95 mTextureID = 0;
96 }
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -070097 if (mRenderTargetID) {
98 glDeleteRenderbuffers(1, &mRenderTargetID);
99 mRenderTargetID = 0;
100 }
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800101#endif //ANDROID_RS_SERIALIZE
Jason Sams326e0dd2009-05-22 14:03:28 -0700102}
103
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800104void Allocation::setCpuWritable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700105}
106
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800107void Allocation::setGpuWritable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700108}
109
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800110void Allocation::setCpuReadable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700111}
112
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800113void Allocation::setGpuReadable(bool) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700114}
115
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800116bool Allocation::fixAllocation() {
Jason Sams326e0dd2009-05-22 14:03:28 -0700117 return false;
118}
119
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700120void Allocation::deferredUploadToTexture(const Context *rsc) {
Jason Samsbad80742011-03-16 16:29:28 -0700121 mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700122 mUploadDeferred = true;
123}
124
125void Allocation::deferredAllocateRenderTarget(const Context *rsc) {
126 mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET;
127 mUploadDeferred = true;
Jason Samscf4c7c92009-12-14 12:57:40 -0800128}
129
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800130uint32_t Allocation::getGLTarget() const {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800131#ifndef ANDROID_RS_SERIALIZE
Jason Samsebc50192010-12-13 15:32:35 -0800132 if (getIsTexture()) {
Jason Samsbad80742011-03-16 16:29:28 -0700133 if (mHal.state.type->getDimFaces()) {
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800134 return GL_TEXTURE_CUBE_MAP;
135 } else {
136 return GL_TEXTURE_2D;
137 }
138 }
Jason Samsebc50192010-12-13 15:32:35 -0800139 if (getIsBufferObject()) {
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800140 return GL_ARRAY_BUFFER;
141 }
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800142#endif //ANDROID_RS_SERIALIZE
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800143 return 0;
144}
145
Jason Samsb89b0b72010-12-13 17:11:21 -0800146void Allocation::allocScriptMemory() {
Jason Samsbad80742011-03-16 16:29:28 -0700147 rsAssert(!mHal.state.mallocPtr);
148 mHal.state.mallocPtr = malloc(mHal.state.type->getSizeBytes());
Jason Samsb89b0b72010-12-13 17:11:21 -0800149}
150
151void Allocation::freeScriptMemory() {
Jason Samsbad80742011-03-16 16:29:28 -0700152 if (mHal.state.mallocPtr) {
153 free(mHal.state.mallocPtr);
154 mHal.state.mallocPtr = NULL;
Jason Samsb89b0b72010-12-13 17:11:21 -0800155 }
156}
157
158
Jason Sams366c9c82010-12-08 16:14:36 -0800159void Allocation::syncAll(Context *rsc, RsAllocationUsageType src) {
160 rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);
161
Jason Samsebc50192010-12-13 15:32:35 -0800162 if (getIsTexture()) {
Jason Sams366c9c82010-12-08 16:14:36 -0800163 uploadToTexture(rsc);
164 }
Jason Samsebc50192010-12-13 15:32:35 -0800165 if (getIsBufferObject()) {
Jason Sams366c9c82010-12-08 16:14:36 -0800166 uploadToBufferObject(rsc);
167 }
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700168 if (getIsRenderTarget() && !getIsTexture()) {
169 allocateRenderTarget(rsc);
170 }
Jason Sams366c9c82010-12-08 16:14:36 -0800171
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700172 mUploadDeferred = false;
Jason Sams366c9c82010-12-08 16:14:36 -0800173}
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800174
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800175void Allocation::uploadToTexture(const Context *rsc) {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800176#ifndef ANDROID_RS_SERIALIZE
Jason Samsbad80742011-03-16 16:29:28 -0700177 mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE;
178 GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
179 GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
Jason Sams565ac362009-06-03 16:04:54 -0700180
181 if (!type || !format) {
182 return;
183 }
184
Jason Samsbad80742011-03-16 16:29:28 -0700185 if (!mHal.state.mallocPtr) {
Jason Samsb89b0b72010-12-13 17:11:21 -0800186 return;
187 }
188
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700189 bool isFirstUpload = false;
190
Jason Sams326e0dd2009-05-22 14:03:28 -0700191 if (!mTextureID) {
192 glGenTextures(1, &mTextureID);
Jason Sams13e26342009-11-24 12:26:35 -0800193
194 if (!mTextureID) {
195 // This should not happen, however, its likely the cause of the
196 // white sqare bug.
197 // Force a crash to 1: restart the app, 2: make sure we get a bugreport.
198 LOGE("Upload to texture failed to gen mTextureID");
199 rsc->dumpDebug();
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700200 mUploadDeferred = true;
Jason Samscf4c7c92009-12-14 12:57:40 -0800201 return;
Jason Sams13e26342009-11-24 12:26:35 -0800202 }
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700203 isFirstUpload = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700204 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800205
Jason Samsbcac9342011-01-13 17:38:18 -0800206 upload2DTexture(isFirstUpload);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800207
Jason Samsbad80742011-03-16 16:29:28 -0700208 if (!(mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
Jason Samsb89b0b72010-12-13 17:11:21 -0800209 freeScriptMemory();
210 }
211
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800212 rsc->checkError("Allocation::uploadToTexture");
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800213#endif //ANDROID_RS_SERIALIZE
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800214}
215
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700216void Allocation::allocateRenderTarget(const Context *rsc) {
217#ifndef ANDROID_RS_SERIALIZE
218 mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET;
219
220 GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
221 if (!format) {
222 return;
223 }
224
225 if (!mRenderTargetID) {
226 glGenRenderbuffers(1, &mRenderTargetID);
227
228 if (!mRenderTargetID) {
229 // This should generally not happen
230 LOGE("allocateRenderTarget failed to gen mRenderTargetID");
231 rsc->dumpDebug();
232 return;
233 }
234 glBindRenderbuffer(GL_RENDERBUFFER, mRenderTargetID);
235 glRenderbufferStorage(GL_RENDERBUFFER, format,
236 mHal.state.type->getDimX(),
237 mHal.state.type->getDimY());
238 }
239#endif //ANDROID_RS_SERIALIZE
240}
241
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800242#ifndef ANDROID_RS_SERIALIZE
Jason Samsbcac9342011-01-13 17:38:18 -0800243const static GLenum gFaceOrder[] = {
244 GL_TEXTURE_CUBE_MAP_POSITIVE_X,
245 GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
246 GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
247 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
248 GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
249 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
250};
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800251#endif //ANDROID_RS_SERIALIZE
Jason Samsbcac9342011-01-13 17:38:18 -0800252
Jason Sams236385b2011-01-12 14:53:25 -0800253void Allocation::update2DTexture(const void *ptr, uint32_t xoff, uint32_t yoff,
254 uint32_t lod, RsAllocationCubemapFace face,
255 uint32_t w, uint32_t h) {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800256#ifndef ANDROID_RS_SERIALIZE
Jason Samsbad80742011-03-16 16:29:28 -0700257 GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
258 GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
Jason Sams236385b2011-01-12 14:53:25 -0800259 GLenum target = (GLenum)getGLTarget();
Jason Sams185b8b02011-01-16 14:54:28 -0800260 rsAssert(mTextureID);
Jason Sams236385b2011-01-12 14:53:25 -0800261 glBindTexture(target, mTextureID);
262 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Jason Samsbcac9342011-01-13 17:38:18 -0800263 GLenum t = GL_TEXTURE_2D;
Jason Samsbad80742011-03-16 16:29:28 -0700264 if (mHal.state.hasFaces) {
Jason Samsbcac9342011-01-13 17:38:18 -0800265 t = gFaceOrder[face];
266 }
267 glTexSubImage2D(t, lod, xoff, yoff, w, h, format, type, ptr);
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800268#endif //ANDROID_RS_SERIALIZE
Jason Sams236385b2011-01-12 14:53:25 -0800269}
270
Jason Samsbcac9342011-01-13 17:38:18 -0800271void Allocation::upload2DTexture(bool isFirstUpload) {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800272#ifndef ANDROID_RS_SERIALIZE
Jason Samsbad80742011-03-16 16:29:28 -0700273 GLenum type = mHal.state.type->getElement()->getComponent().getGLType();
274 GLenum format = mHal.state.type->getElement()->getComponent().getGLFormat();
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800275
Jason Samsb89b0b72010-12-13 17:11:21 -0800276 GLenum target = (GLenum)getGLTarget();
277 glBindTexture(target, mTextureID);
278 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Jason Sams326e0dd2009-05-22 14:03:28 -0700279
Jason Samsbcac9342011-01-13 17:38:18 -0800280 uint32_t faceCount = 1;
Jason Samsbad80742011-03-16 16:29:28 -0700281 if (mHal.state.hasFaces) {
Jason Samsbcac9342011-01-13 17:38:18 -0800282 faceCount = 6;
Jason Sams326e0dd2009-05-22 14:03:28 -0700283 }
Jason Samsb7e83bd2010-12-15 01:41:00 -0800284
Jason Samsbcac9342011-01-13 17:38:18 -0800285 for (uint32_t face = 0; face < faceCount; face ++) {
Jason Samsbad80742011-03-16 16:29:28 -0700286 for (uint32_t lod = 0; lod < mHal.state.type->getLODCount(); lod++) {
287 const uint8_t *p = (const uint8_t *)mHal.state.mallocPtr;
288 p += mHal.state.type->getLODFaceOffset(lod, (RsAllocationCubemapFace)face, 0, 0);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800289
Jason Samsbcac9342011-01-13 17:38:18 -0800290 GLenum t = GL_TEXTURE_2D;
Jason Samsbad80742011-03-16 16:29:28 -0700291 if (mHal.state.hasFaces) {
Jason Samsbcac9342011-01-13 17:38:18 -0800292 t = gFaceOrder[face];
293 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800294
295 if (isFirstUpload) {
Jason Samsbcac9342011-01-13 17:38:18 -0800296 glTexImage2D(t, lod, format,
Jason Samsbad80742011-03-16 16:29:28 -0700297 mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
Jason Samsbcac9342011-01-13 17:38:18 -0800298 0, format, type, p);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800299 } else {
Jason Samsbcac9342011-01-13 17:38:18 -0800300 glTexSubImage2D(t, lod, 0, 0,
Jason Samsbad80742011-03-16 16:29:28 -0700301 mHal.state.type->getLODDimX(lod), mHal.state.type->getLODDimY(lod),
Jason Samsbcac9342011-01-13 17:38:18 -0800302 format, type, p);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800303 }
304 }
305 }
Jason Samsb7e83bd2010-12-15 01:41:00 -0800306
Jason Samsbad80742011-03-16 16:29:28 -0700307 if (mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
Jason Samsb7e83bd2010-12-15 01:41:00 -0800308 glGenerateMipmap(target);
Jason Samsb7e83bd2010-12-15 01:41:00 -0800309 }
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800310#endif //ANDROID_RS_SERIALIZE
Jason Sams326e0dd2009-05-22 14:03:28 -0700311}
312
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700313void Allocation::deferredUploadToBufferObject(const Context *rsc) {
Jason Samsbad80742011-03-16 16:29:28 -0700314 mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700315 mUploadDeferred = true;
Jason Samscf4c7c92009-12-14 12:57:40 -0800316}
317
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800318void Allocation::uploadToBufferObject(const Context *rsc) {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800319#ifndef ANDROID_RS_SERIALIZE
Jason Samsbad80742011-03-16 16:29:28 -0700320 rsAssert(!mHal.state.type->getDimY());
321 rsAssert(!mHal.state.type->getDimZ());
Jason Sams326e0dd2009-05-22 14:03:28 -0700322
Jason Samsbad80742011-03-16 16:29:28 -0700323 mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;
Jason Samscf4c7c92009-12-14 12:57:40 -0800324
Jason Sams326e0dd2009-05-22 14:03:28 -0700325 if (!mBufferID) {
326 glGenBuffers(1, &mBufferID);
327 }
Jason Samscf4c7c92009-12-14 12:57:40 -0800328 if (!mBufferID) {
329 LOGE("Upload to buffer object failed");
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700330 mUploadDeferred = true;
Jason Samscf4c7c92009-12-14 12:57:40 -0800331 return;
332 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800333 GLenum target = (GLenum)getGLTarget();
334 glBindBuffer(target, mBufferID);
Jason Samsbad80742011-03-16 16:29:28 -0700335 glBufferData(target, mHal.state.type->getSizeBytes(), getPtr(), GL_DYNAMIC_DRAW);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800336 glBindBuffer(target, 0);
Jason Samsc1ed5892010-03-10 17:30:41 -0800337 rsc->checkError("Allocation::uploadToBufferObject");
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800338#endif //ANDROID_RS_SERIALIZE
Jason Sams326e0dd2009-05-22 14:03:28 -0700339}
340
Jason Sams366c9c82010-12-08 16:14:36 -0800341void Allocation::uploadCheck(Context *rsc) {
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700342 if (mUploadDeferred) {
Jason Sams366c9c82010-12-08 16:14:36 -0800343 syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
Jason Samscf4c7c92009-12-14 12:57:40 -0800344 }
345}
346
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800347void Allocation::read(void *data) {
Jason Samsbad80742011-03-16 16:29:28 -0700348 memcpy(data, mHal.state.mallocPtr, mHal.state.type->getSizeBytes());
Jason Samse579df42009-08-10 14:55:26 -0700349}
350
Jason Sams4b45b892010-12-29 14:31:29 -0800351void Allocation::data(Context *rsc, uint32_t xoff, uint32_t lod,
352 uint32_t count, const void *data, uint32_t sizeBytes) {
Jason Samsbad80742011-03-16 16:29:28 -0700353 uint32_t eSize = mHal.state.type->getElementSizeBytes();
354 uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
Jason Sams326e0dd2009-05-22 14:03:28 -0700355 ptr += eSize * xoff;
Jason Sams9397e302009-08-27 20:23:34 -0700356 uint32_t size = count * eSize;
357
358 if (size != sizeBytes) {
359 LOGE("Allocation::subData called with mismatched size expected %i, got %i", size, sizeBytes);
Jason Samsbad80742011-03-16 16:29:28 -0700360 mHal.state.type->dumpLOGV("type info");
Jason Sams9397e302009-08-27 20:23:34 -0700361 return;
362 }
Jason Samse3929c92010-08-09 18:13:33 -0700363
Jason Samsbad80742011-03-16 16:29:28 -0700364 if (mHal.state.hasReferences) {
Jason Samse3929c92010-08-09 18:13:33 -0700365 incRefs(data, count);
366 decRefs(ptr, count);
367 }
368
Jason Sams9397e302009-08-27 20:23:34 -0700369 memcpy(ptr, data, size);
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700370 sendDirty();
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700371 mUploadDeferred = true;
Jason Sams326e0dd2009-05-22 14:03:28 -0700372}
373
Jason Sams4b45b892010-12-29 14:31:29 -0800374void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800375 uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
Jason Samsbad80742011-03-16 16:29:28 -0700376 uint32_t eSize = mHal.state.elementSizeBytes;
Jason Sams326e0dd2009-05-22 14:03:28 -0700377 uint32_t lineSize = eSize * w;
Jason Samsbad80742011-03-16 16:29:28 -0700378 uint32_t destW = mHal.state.dimensionX;
Jason Sams326e0dd2009-05-22 14:03:28 -0700379
Jason Samsa2371512011-01-12 13:28:37 -0800380 //LOGE("data2d %p, %i %i %i %i %i %i %p %i", this, xoff, yoff, lod, face, w, h, data, sizeBytes);
Jason Sams9397e302009-08-27 20:23:34 -0700381
Jason Samsa2371512011-01-12 13:28:37 -0800382 if ((lineSize * h) != sizeBytes) {
383 LOGE("Allocation size mismatch, expected %i, got %i", (lineSize * h), sizeBytes);
Jason Sams9397e302009-08-27 20:23:34 -0700384 rsAssert(!"Allocation::subData called with mismatched size");
385 return;
386 }
387
Jason Samsbad80742011-03-16 16:29:28 -0700388 if (mHal.state.mallocPtr) {
Jason Samsa2371512011-01-12 13:28:37 -0800389 const uint8_t *src = static_cast<const uint8_t *>(data);
Jason Samsbad80742011-03-16 16:29:28 -0700390 uint8_t *dst = static_cast<uint8_t *>(mHal.state.mallocPtr);
391 dst += mHal.state.type->getLODFaceOffset(lod, face, xoff, yoff);
Jason Samsa2371512011-01-12 13:28:37 -0800392
393 //LOGE(" %p %p %i ", dst, src, eSize);
394 for (uint32_t line=yoff; line < (yoff+h); line++) {
Jason Samsbad80742011-03-16 16:29:28 -0700395 if (mHal.state.hasReferences) {
Jason Samsa2371512011-01-12 13:28:37 -0800396 incRefs(src, w);
397 decRefs(dst, w);
398 }
399 memcpy(dst, src, lineSize);
400 src += lineSize;
401 dst += destW * eSize;
Jason Samse3929c92010-08-09 18:13:33 -0700402 }
Jason Samsa2371512011-01-12 13:28:37 -0800403 sendDirty();
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700404 mUploadDeferred = true;
Jason Samsa2371512011-01-12 13:28:37 -0800405 } else {
Jason Sams236385b2011-01-12 14:53:25 -0800406 update2DTexture(data, xoff, yoff, lod, face, w, h);
Jason Sams326e0dd2009-05-22 14:03:28 -0700407 }
408}
409
Jason Sams236385b2011-01-12 14:53:25 -0800410void Allocation::data(Context *rsc, uint32_t xoff, uint32_t yoff, uint32_t zoff,
411 uint32_t lod, RsAllocationCubemapFace face,
412 uint32_t w, uint32_t h, uint32_t d, const void *data, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700413}
414
Jason Sams4b45b892010-12-29 14:31:29 -0800415void Allocation::elementData(Context *rsc, uint32_t x, const void *data,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800416 uint32_t cIdx, uint32_t sizeBytes) {
Jason Samsbad80742011-03-16 16:29:28 -0700417 uint32_t eSize = mHal.state.elementSizeBytes;
418 uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700419 ptr += eSize * x;
420
Jason Samsbad80742011-03-16 16:29:28 -0700421 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700422 LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
423 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
424 return;
425 }
426
Jason Samsbad80742011-03-16 16:29:28 -0700427 if (x >= mHal.state.dimensionX) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700428 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
429 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
430 return;
431 }
432
Jason Samsbad80742011-03-16 16:29:28 -0700433 const Element * e = mHal.state.type->getElement()->getField(cIdx);
434 ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700435
436 if (sizeBytes != e->getSizeBytes()) {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800437 LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
Jason Sams5f0c84c2010-08-31 13:50:42 -0700438 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
439 return;
440 }
441
442 if (e->getHasReferences()) {
443 e->incRefs(data);
444 e->decRefs(ptr);
445 }
446
447 memcpy(ptr, data, sizeBytes);
448 sendDirty();
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700449 mUploadDeferred = true;
Jason Sams5f0c84c2010-08-31 13:50:42 -0700450}
451
Jason Sams4b45b892010-12-29 14:31:29 -0800452void Allocation::elementData(Context *rsc, uint32_t x, uint32_t y,
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800453 const void *data, uint32_t cIdx, uint32_t sizeBytes) {
Jason Samsbad80742011-03-16 16:29:28 -0700454 uint32_t eSize = mHal.state.elementSizeBytes;
455 uint8_t * ptr = static_cast<uint8_t *>(mHal.state.mallocPtr);
456 ptr += eSize * (x + y * mHal.state.dimensionX);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700457
Jason Samsbad80742011-03-16 16:29:28 -0700458 if (x >= mHal.state.dimensionX) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700459 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
460 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
461 return;
462 }
463
Jason Samsbad80742011-03-16 16:29:28 -0700464 if (y >= mHal.state.dimensionY) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700465 LOGE("Error Allocation::subElementData X offset %i out of range.", x);
466 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData X offset out of range.");
467 return;
468 }
469
Jason Samsbad80742011-03-16 16:29:28 -0700470 if (cIdx >= mHal.state.type->getElement()->getFieldCount()) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700471 LOGE("Error Allocation::subElementData component %i out of range.", cIdx);
472 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData component out of range.");
473 return;
474 }
475
Jason Samsbad80742011-03-16 16:29:28 -0700476 const Element * e = mHal.state.type->getElement()->getField(cIdx);
477 ptr += mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700478
479 if (sizeBytes != e->getSizeBytes()) {
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800480 LOGE("Error Allocation::subElementData data size %i does not match field size %zu.", sizeBytes, e->getSizeBytes());
Jason Sams5f0c84c2010-08-31 13:50:42 -0700481 rsc->setError(RS_ERROR_BAD_VALUE, "subElementData bad size.");
482 return;
483 }
484
485 if (e->getHasReferences()) {
486 e->incRefs(data);
487 e->decRefs(ptr);
488 }
489
490 memcpy(ptr, data, sizeBytes);
491 sendDirty();
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700492 mUploadDeferred = true;
Jason Sams5f0c84c2010-08-31 13:50:42 -0700493}
494
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800495void Allocation::addProgramToDirty(const Program *p) {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800496#ifndef ANDROID_RS_SERIALIZE
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700497 mToDirtyList.push(p);
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800498#endif //ANDROID_RS_SERIALIZE
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700499}
Jason Sams326e0dd2009-05-22 14:03:28 -0700500
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800501void Allocation::removeProgramToDirty(const Program *p) {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800502#ifndef ANDROID_RS_SERIALIZE
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700503 for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
504 if (mToDirtyList[ct] == p) {
505 mToDirtyList.removeAt(ct);
506 return;
507 }
508 }
509 rsAssert(0);
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800510#endif //ANDROID_RS_SERIALIZE
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700511}
512
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800513void Allocation::dumpLOGV(const char *prefix) const {
Jason Samsc21cf402009-11-17 17:26:46 -0800514 ObjectBase::dumpLOGV(prefix);
515
516 String8 s(prefix);
517 s.append(" type ");
Jason Samsbad80742011-03-16 16:29:28 -0700518 if (mHal.state.type.get()) {
519 mHal.state.type->dumpLOGV(s.string());
Jason Samsc21cf402009-11-17 17:26:46 -0800520 }
521
522 LOGV("%s allocation ptr=%p mCpuWrite=%i, mCpuRead=%i, mGpuWrite=%i, mGpuRead=%i",
Jason Samsbad80742011-03-16 16:29:28 -0700523 prefix, mHal.state.mallocPtr, mCpuWrite, mCpuRead, mGpuWrite, mGpuRead);
Jason Samsc21cf402009-11-17 17:26:46 -0800524
Jason Samsebc50192010-12-13 15:32:35 -0800525 LOGV("%s allocation mUsageFlags=0x04%x, mMipmapControl=0x%04x, mTextureID=%i, mBufferID=%i",
Jason Samsbad80742011-03-16 16:29:28 -0700526 prefix, mHal.state.usageFlags, mHal.state.mipmapControl, mTextureID, mBufferID);
Jason Samsc21cf402009-11-17 17:26:46 -0800527}
Jason Sams326e0dd2009-05-22 14:03:28 -0700528
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800529void Allocation::serialize(OStream *stream) const {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700530 // Need to identify ourselves
531 stream->addU32((uint32_t)getClassId());
532
533 String8 name(getName());
534 stream->addString(&name);
535
536 // First thing we need to serialize is the type object since it will be needed
537 // to initialize the class
Jason Samsbad80742011-03-16 16:29:28 -0700538 mHal.state.type->serialize(stream);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700539
Jason Samsbad80742011-03-16 16:29:28 -0700540 uint32_t dataSize = mHal.state.type->getSizeBytes();
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700541 // Write how much data we are storing
542 stream->addU32(dataSize);
543 // Now write the data
Jason Samsbad80742011-03-16 16:29:28 -0700544 stream->addByteArray(mHal.state.mallocPtr, dataSize);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700545}
546
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800547Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700548 // First make sure we are reading the correct object
Alex Sakhartchoukb825f672010-06-04 10:06:50 -0700549 RsA3DClassID classID = (RsA3DClassID)stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800550 if (classID != RS_A3D_CLASS_ID_ALLOCATION) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700551 LOGE("allocation loading skipped due to invalid class id\n");
552 return NULL;
553 }
554
555 String8 name;
556 stream->loadString(&name);
557
558 Type *type = Type::createFromStream(rsc, stream);
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800559 if (!type) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700560 return NULL;
561 }
562 type->compute();
563
564 // Number of bytes we wrote out for this allocation
565 uint32_t dataSize = stream->loadU32();
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800566 if (dataSize != type->getSizeBytes()) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700567 LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
Jason Sams225afd32010-10-21 14:06:55 -0700568 ObjectBase::checkDelete(type);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700569 return NULL;
570 }
571
Jason Samsebc50192010-12-13 15:32:35 -0800572 Allocation *alloc = new Allocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700573 alloc->setName(name.string(), name.size());
574
Jason Sams4b45b892010-12-29 14:31:29 -0800575 uint32_t count = dataSize / type->getElementSizeBytes();
576
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700577 // Read in all of our allocation data
Jason Sams4b45b892010-12-29 14:31:29 -0800578 alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
Alex Sakhartchouke6d9fbc2010-08-11 10:30:44 -0700579 stream->reset(stream->getPos() + dataSize);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700580
581 return alloc;
582}
583
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800584void Allocation::sendDirty() const {
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800585#ifndef ANDROID_RS_SERIALIZE
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700586 for (size_t ct=0; ct < mToDirtyList.size(); ct++) {
587 mToDirtyList[ct]->forceDirty();
588 }
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800589#endif //ANDROID_RS_SERIALIZE
Jason Sams5c3e3bc2009-10-26 15:19:28 -0700590}
Jason Sams326e0dd2009-05-22 14:03:28 -0700591
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800592void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const {
Jason Samse3929c92010-08-09 18:13:33 -0700593 const uint8_t *p = static_cast<const uint8_t *>(ptr);
Jason Samsbad80742011-03-16 16:29:28 -0700594 const Element *e = mHal.state.type->getElement();
Jason Samse3929c92010-08-09 18:13:33 -0700595 uint32_t stride = e->getSizeBytes();
596
Jason Sams96abf812010-10-05 13:32:49 -0700597 p += stride * startOff;
Jason Samse3929c92010-08-09 18:13:33 -0700598 while (ct > 0) {
599 e->incRefs(p);
600 ct --;
601 p += stride;
602 }
603}
604
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800605void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const {
Jason Samse3929c92010-08-09 18:13:33 -0700606 const uint8_t *p = static_cast<const uint8_t *>(ptr);
Jason Samsbad80742011-03-16 16:29:28 -0700607 const Element *e = mHal.state.type->getElement();
Jason Samse3929c92010-08-09 18:13:33 -0700608 uint32_t stride = e->getSizeBytes();
609
Jason Sams96abf812010-10-05 13:32:49 -0700610 p += stride * startOff;
Jason Samse3929c92010-08-09 18:13:33 -0700611 while (ct > 0) {
612 e->decRefs(p);
613 ct --;
614 p += stride;
615 }
616}
617
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800618void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len) {
Jason Sams96abf812010-10-05 13:32:49 -0700619}
620
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800621void Allocation::resize1D(Context *rsc, uint32_t dimX) {
Jason Samsbad80742011-03-16 16:29:28 -0700622 Type *t = mHal.state.type->cloneAndResize1D(rsc, dimX);
Jason Sams96abf812010-10-05 13:32:49 -0700623
Jason Samsbad80742011-03-16 16:29:28 -0700624 uint32_t oldDimX = mHal.state.dimensionX;
Jason Sams96abf812010-10-05 13:32:49 -0700625 if (dimX == oldDimX) {
626 return;
627 }
628
629 if (dimX < oldDimX) {
Jason Samsbad80742011-03-16 16:29:28 -0700630 decRefs(mHal.state.mallocPtr, oldDimX - dimX, dimX);
Jason Sams96abf812010-10-05 13:32:49 -0700631 }
Jason Samsbad80742011-03-16 16:29:28 -0700632 mHal.state.mallocPtr = realloc(mHal.state.mallocPtr, t->getSizeBytes());
Jason Sams96abf812010-10-05 13:32:49 -0700633
634 if (dimX > oldDimX) {
Jason Samsbad80742011-03-16 16:29:28 -0700635 const Element *e = mHal.state.type->getElement();
Jason Sams96abf812010-10-05 13:32:49 -0700636 uint32_t stride = e->getSizeBytes();
Jason Samsbad80742011-03-16 16:29:28 -0700637 memset(((uint8_t *)mHal.state.mallocPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
Jason Sams96abf812010-10-05 13:32:49 -0700638 }
Jason Samsbad80742011-03-16 16:29:28 -0700639
640 mHal.state.type.set(t);
641 updateCache();
Jason Sams96abf812010-10-05 13:32:49 -0700642}
643
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800644void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY) {
Jason Sams96abf812010-10-05 13:32:49 -0700645 LOGE("not implemented");
646}
647
Jason Sams326e0dd2009-05-22 14:03:28 -0700648/////////////////
Jason Sams565ac362009-06-03 16:04:54 -0700649//
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800650#ifndef ANDROID_RS_SERIALIZE
Jason Sams326e0dd2009-05-22 14:03:28 -0700651
Stephen Hines6a121812011-03-01 17:34:59 -0800652
Jason Sams326e0dd2009-05-22 14:03:28 -0700653namespace android {
654namespace renderscript {
655
Jason Samsc975cf42011-04-28 18:26:48 -0700656static void AllocationGenerateScriptMips(RsContext con, RsAllocation va);
657
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800658void rsi_AllocationUploadToTexture(Context *rsc, RsAllocation va, bool genmip, uint32_t baseMipLevel) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700659 Allocation *alloc = static_cast<Allocation *>(va);
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700660 alloc->deferredUploadToTexture(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -0700661}
662
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800663void rsi_AllocationUploadToBufferObject(Context *rsc, RsAllocation va) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700664 Allocation *alloc = static_cast<Allocation *>(va);
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700665 alloc->deferredUploadToBufferObject(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -0700666}
667
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800668static void mip565(const Adapter2D &out, const Adapter2D &in) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700669 uint32_t w = out.getDimX();
670 uint32_t h = out.getDimY();
671
Jason Samse9f5c532009-07-28 17:20:11 -0700672 for (uint32_t y=0; y < h; y++) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700673 uint16_t *oPtr = static_cast<uint16_t *>(out.getElement(0, y));
674 const uint16_t *i1 = static_cast<uint16_t *>(in.getElement(0, y*2));
675 const uint16_t *i2 = static_cast<uint16_t *>(in.getElement(0, y*2+1));
676
Jason Samse9f5c532009-07-28 17:20:11 -0700677 for (uint32_t x=0; x < w; x++) {
Jason Sams565ac362009-06-03 16:04:54 -0700678 *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
679 oPtr ++;
680 i1 += 2;
681 i2 += 2;
682 }
683 }
684}
685
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800686static void mip8888(const Adapter2D &out, const Adapter2D &in) {
Jason Sams565ac362009-06-03 16:04:54 -0700687 uint32_t w = out.getDimX();
688 uint32_t h = out.getDimY();
689
Jason Samse9f5c532009-07-28 17:20:11 -0700690 for (uint32_t y=0; y < h; y++) {
Jason Sams565ac362009-06-03 16:04:54 -0700691 uint32_t *oPtr = static_cast<uint32_t *>(out.getElement(0, y));
692 const uint32_t *i1 = static_cast<uint32_t *>(in.getElement(0, y*2));
693 const uint32_t *i2 = static_cast<uint32_t *>(in.getElement(0, y*2+1));
694
Jason Samse9f5c532009-07-28 17:20:11 -0700695 for (uint32_t x=0; x < w; x++) {
Jason Sams565ac362009-06-03 16:04:54 -0700696 *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
Jason Sams326e0dd2009-05-22 14:03:28 -0700697 oPtr ++;
698 i1 += 2;
699 i2 += 2;
700 }
701 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700702}
703
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800704static void mip8(const Adapter2D &out, const Adapter2D &in) {
Jason Sams2f6d8612010-01-19 17:53:54 -0800705 uint32_t w = out.getDimX();
706 uint32_t h = out.getDimY();
707
708 for (uint32_t y=0; y < h; y++) {
709 uint8_t *oPtr = static_cast<uint8_t *>(out.getElement(0, y));
710 const uint8_t *i1 = static_cast<uint8_t *>(in.getElement(0, y*2));
711 const uint8_t *i2 = static_cast<uint8_t *>(in.getElement(0, y*2+1));
712
713 for (uint32_t x=0; x < w; x++) {
714 *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
715 oPtr ++;
716 i1 += 2;
717 i2 += 2;
718 }
719 }
720}
721
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800722static void mip(const Adapter2D &out, const Adapter2D &in) {
723 switch (out.getBaseType()->getElement()->getSizeBits()) {
Jason Samse9f5c532009-07-28 17:20:11 -0700724 case 32:
725 mip8888(out, in);
726 break;
727 case 16:
728 mip565(out, in);
729 break;
Jason Sams2f6d8612010-01-19 17:53:54 -0800730 case 8:
731 mip8(out, in);
732 break;
Jason Samse9f5c532009-07-28 17:20:11 -0700733 }
Jason Samse9f5c532009-07-28 17:20:11 -0700734}
Jason Sams326e0dd2009-05-22 14:03:28 -0700735
Jason Sams366c9c82010-12-08 16:14:36 -0800736void rsi_AllocationSyncAll(Context *rsc, RsAllocation va, RsAllocationUsageType src) {
737 Allocation *a = static_cast<Allocation *>(va);
738 a->syncAll(rsc, src);
Jason Sams09aeb8a2011-01-28 15:49:07 -0800739 a->sendDirty();
Jason Sams366c9c82010-12-08 16:14:36 -0800740}
741
Jason Samsa2371512011-01-12 13:28:37 -0800742void rsi_AllocationGenerateMipmaps(Context *rsc, RsAllocation va) {
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700743 Allocation *texAlloc = static_cast<Allocation *>(va);
Jason Samsc975cf42011-04-28 18:26:48 -0700744 AllocationGenerateScriptMips(rsc, texAlloc);
Jason Sams837e3882010-12-10 16:03:15 -0800745}
746
747void rsi_AllocationCopyToBitmap(Context *rsc, RsAllocation va, void *data, size_t dataLen) {
748 Allocation *texAlloc = static_cast<Allocation *>(va);
749 const Type * t = texAlloc->getType();
750
751 size_t s = t->getDimX() * t->getDimY() * t->getElementSizeBytes();
752 if (s != dataLen) {
753 rsc->setError(RS_ERROR_BAD_VALUE, "Bitmap size didn't match allocation size");
754 return;
755 }
756
757 memcpy(data, texAlloc->getPtr(), s);
Alex Sakhartchouk39f2ef62010-10-11 12:35:15 -0700758}
759
Jason Sams4b45b892010-12-29 14:31:29 -0800760void rsi_Allocation1DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t lod,
761 uint32_t count, const void *data, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700762 Allocation *a = static_cast<Allocation *>(va);
Jason Sams4b45b892010-12-29 14:31:29 -0800763 a->data(rsc, xoff, lod, count, data, sizeBytes);
Jason Sams326e0dd2009-05-22 14:03:28 -0700764}
765
Jason Sams4b45b892010-12-29 14:31:29 -0800766void rsi_Allocation2DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t y, uint32_t lod, RsAllocationCubemapFace face,
767 const void *data, uint32_t eoff, uint32_t sizeBytes) {
Jason Sams326e0dd2009-05-22 14:03:28 -0700768 Allocation *a = static_cast<Allocation *>(va);
Jason Sams4b45b892010-12-29 14:31:29 -0800769 a->elementData(rsc, x, y, data, eoff, sizeBytes);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700770}
771
Jason Sams4b45b892010-12-29 14:31:29 -0800772void rsi_Allocation1DElementData(Context *rsc, RsAllocation va, uint32_t x, uint32_t lod,
773 const void *data, uint32_t eoff, uint32_t sizeBytes) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700774 Allocation *a = static_cast<Allocation *>(va);
Jason Sams4b45b892010-12-29 14:31:29 -0800775 a->elementData(rsc, x, data, eoff, sizeBytes);
Jason Sams5f0c84c2010-08-31 13:50:42 -0700776}
777
Jason Sams4b45b892010-12-29 14:31:29 -0800778void rsi_Allocation2DData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
779 uint32_t w, uint32_t h, const void *data, uint32_t sizeBytes) {
Jason Sams5f0c84c2010-08-31 13:50:42 -0700780 Allocation *a = static_cast<Allocation *>(va);
Jason Sams4b45b892010-12-29 14:31:29 -0800781 a->data(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
Jason Sams326e0dd2009-05-22 14:03:28 -0700782}
783
Alex Sakhartchouk70b83c12011-04-06 10:57:51 -0700784void rsi_AllocationRead(Context *rsc, RsAllocation va, void *data, size_t data_length) {
Jason Samse579df42009-08-10 14:55:26 -0700785 Allocation *a = static_cast<Allocation *>(va);
786 a->read(data);
787}
788
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800789void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX) {
Jason Sams96abf812010-10-05 13:32:49 -0700790 Allocation *a = static_cast<Allocation *>(va);
791 a->resize1D(rsc, dimX);
792}
793
Alex Sakhartchoukafb743a2010-11-09 17:00:54 -0800794void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY) {
Jason Sams96abf812010-10-05 13:32:49 -0700795 Allocation *a = static_cast<Allocation *>(va);
796 a->resize2D(rsc, dimX, dimY);
797}
798
Jason Samsc975cf42011-04-28 18:26:48 -0700799static void AllocationGenerateScriptMips(RsContext con, RsAllocation va) {
Alex Sakhartchoukf8aafcf2011-01-11 14:47:44 -0800800 Context *rsc = static_cast<Context *>(con);
801 Allocation *texAlloc = static_cast<Allocation *>(va);
802 uint32_t numFaces = texAlloc->getType()->getDimFaces() ? 6 : 1;
803 for (uint32_t face = 0; face < numFaces; face ++) {
804 Adapter2D adapt(rsc, texAlloc);
805 Adapter2D adapt2(rsc, texAlloc);
806 adapt.setFace(face);
807 adapt2.setFace(face);
808 for (uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
809 adapt.setLOD(lod);
810 adapt2.setLOD(lod + 1);
811 mip(adapt2, adapt);
812 }
813 }
814}
815
Jason Samsc975cf42011-04-28 18:26:48 -0700816RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
817 RsAllocationMipmapControl mips,
818 uint32_t usages) {
Alex Sakhartchouka2aab8b2010-12-15 09:59:58 -0800819 Allocation * alloc = new Allocation(rsc, static_cast<Type *>(vtype), usages, mips);
Jason Samsf0c1df42010-10-26 13:09:17 -0700820 alloc->incUserRef();
821 return alloc;
822}
823
Jason Samsc975cf42011-04-28 18:26:48 -0700824RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
825 RsAllocationMipmapControl mips,
826 const void *data, size_t data_length, uint32_t usages) {
Jason Sams366c9c82010-12-08 16:14:36 -0800827 Type *t = static_cast<Type *>(vtype);
Jason Samsf0c1df42010-10-26 13:09:17 -0700828
Jason Samsc975cf42011-04-28 18:26:48 -0700829 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
Jason Samsf0c1df42010-10-26 13:09:17 -0700830 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
831 if (texAlloc == NULL) {
832 LOGE("Memory allocation failure");
833 return NULL;
834 }
835
Jason Sams366c9c82010-12-08 16:14:36 -0800836 memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
Jason Samsebc50192010-12-13 15:32:35 -0800837 if (mips == RS_ALLOCATION_MIPMAP_FULL) {
Jason Samsc975cf42011-04-28 18:26:48 -0700838 AllocationGenerateScriptMips(rsc, texAlloc);
Jason Samsf0c1df42010-10-26 13:09:17 -0700839 }
840
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700841 texAlloc->deferredUploadToTexture(rsc);
Jason Samsf0c1df42010-10-26 13:09:17 -0700842 return texAlloc;
843}
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800844
Jason Samsc975cf42011-04-28 18:26:48 -0700845RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
846 RsAllocationMipmapControl mips,
847 const void *data, size_t data_length, uint32_t usages) {
Jason Sams366c9c82010-12-08 16:14:36 -0800848 Type *t = static_cast<Type *>(vtype);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800849
850 // Cubemap allocation's faces should be Width by Width each.
851 // Source data should have 6 * Width by Width pixels
852 // Error checking is done in the java layer
Jason Samsc975cf42011-04-28 18:26:48 -0700853 RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800854 Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
855 if (texAlloc == NULL) {
856 LOGE("Memory allocation failure");
857 return NULL;
858 }
859
Alex Sakhartchouk9f8bc4f2011-01-10 15:57:57 -0800860 uint32_t faceSize = t->getDimX();
861 uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
862 uint32_t copySize = faceSize * t->getElementSizeBytes();
863
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800864 uint8_t *sourcePtr = (uint8_t*)data;
Jason Sams366c9c82010-12-08 16:14:36 -0800865 for (uint32_t face = 0; face < 6; face ++) {
866 Adapter2D faceAdapter(rsc, texAlloc);
867 faceAdapter.setFace(face);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800868
Alex Sakhartchouk9f8bc4f2011-01-10 15:57:57 -0800869 for (uint32_t dI = 0; dI < faceSize; dI ++) {
870 memcpy(faceAdapter.getElement(0, dI), sourcePtr + strideBytes * dI, copySize);
871 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800872
Jason Sams366c9c82010-12-08 16:14:36 -0800873 // Move the data pointer to the next cube face
Alex Sakhartchouk9f8bc4f2011-01-10 15:57:57 -0800874 sourcePtr += copySize;
Alex Sakhartchoukf8aafcf2011-01-11 14:47:44 -0800875 }
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800876
Alex Sakhartchoukf8aafcf2011-01-11 14:47:44 -0800877 if (mips == RS_ALLOCATION_MIPMAP_FULL) {
Jason Samsc975cf42011-04-28 18:26:48 -0700878 AllocationGenerateScriptMips(rsc, texAlloc);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800879 }
880
Alex Sakhartchouk7d9c5ff2011-04-01 14:19:01 -0700881 texAlloc->deferredUploadToTexture(rsc);
Alex Sakhartchouk84e40272010-11-18 15:22:43 -0800882 return texAlloc;
883}
Alex Sakhartchouk099d7d32011-01-28 09:31:47 -0800884
Jason Samsc975cf42011-04-28 18:26:48 -0700885}
886}
887
888const void * rsaAllocationGetType(RsContext con, RsAllocation va) {
889 Allocation *a = static_cast<Allocation *>(va);
890 a->getType()->incUserRef();
891
892 return a->getType();
893}
894
Alex Sakhartchouk77d9f4b2011-01-31 14:53:24 -0800895#endif //ANDROID_RS_SERIALIZE