Allocation.java revision d26297fa562d8bb203df1bb5e6ded7f62c56cdb7
1/* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package android.renderscript; 18 19import java.io.IOException; 20import java.io.InputStream; 21 22import android.content.res.Resources; 23import android.content.res.AssetManager; 24import android.graphics.Bitmap; 25import android.graphics.BitmapFactory; 26import android.util.Log; 27import android.util.TypedValue; 28 29/** 30 * @hide 31 * 32 **/ 33public class Allocation extends BaseObj { 34 Type mType; 35 Bitmap mBitmap; 36 37 Allocation(int id, RenderScript rs, Type t) { 38 super(id, rs); 39 mType = t; 40 } 41 42 Allocation(int id, RenderScript rs) { 43 super(id, rs); 44 } 45 46 @Override 47 void updateFromNative() { 48 mRS.validate(); 49 mName = mRS.nGetName(mID); 50 int typeID = mRS.nAllocationGetType(mID); 51 if(typeID != 0) { 52 mType = new Type(typeID, mRS); 53 mType.updateFromNative(); 54 } 55 } 56 57 public Type getType() { 58 return mType; 59 } 60 61 public void uploadToTexture(int baseMipLevel) { 62 mRS.validate(); 63 mRS.nAllocationUploadToTexture(mID, false, baseMipLevel); 64 } 65 66 public void uploadToTexture(boolean genMips, int baseMipLevel) { 67 mRS.validate(); 68 mRS.nAllocationUploadToTexture(mID, genMips, baseMipLevel); 69 } 70 71 public void uploadToBufferObject() { 72 mRS.validate(); 73 mRS.nAllocationUploadToBufferObject(mID); 74 } 75 76 public void data(int[] d) { 77 mRS.validate(); 78 subData1D(0, mType.getElementCount(), d); 79 } 80 public void data(short[] d) { 81 mRS.validate(); 82 subData1D(0, mType.getElementCount(), d); 83 } 84 public void data(byte[] d) { 85 mRS.validate(); 86 subData1D(0, mType.getElementCount(), d); 87 } 88 public void data(float[] d) { 89 mRS.validate(); 90 subData1D(0, mType.getElementCount(), d); 91 } 92 93 public void updateFromBitmap(Bitmap b) 94 throws IllegalArgumentException { 95 96 mRS.validate(); 97 if(mType.getX() != b.getWidth() || 98 mType.getY() != b.getHeight()) { 99 throw new IllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch"); 100 } 101 102 mRS.nAllocationUpdateFromBitmap(mID, b); 103 } 104 105 public void subData(int xoff, FieldPacker fp) { 106 int eSize = mType.mElement.getSizeBytes(); 107 final byte[] data = fp.getData(); 108 109 int count = data.length / eSize; 110 if ((eSize * count) != data.length) { 111 throw new IllegalArgumentException("Field packer length " + data.length + 112 " not divisible by element size " + eSize + "."); 113 } 114 data1DChecks(xoff, count, data.length, data.length); 115 mRS.nAllocationSubData1D(mID, xoff, count, data, data.length); 116 } 117 118 119 public void subElementData(int xoff, int component_number, FieldPacker fp) { 120 if (component_number >= mType.mElement.mElements.length) { 121 throw new IllegalArgumentException("Component_number " + component_number + " out of range."); 122 } 123 if(xoff < 0) { 124 throw new IllegalArgumentException("Offset must be >= 0."); 125 } 126 127 final byte[] data = fp.getData(); 128 int eSize = mType.mElement.mElements[component_number].getSizeBytes(); 129 130 if (data.length != eSize) { 131 throw new IllegalArgumentException("Field packer sizelength " + data.length + 132 " does not match component size " + eSize + "."); 133 } 134 135 mRS.nAllocationSubElementData1D(mID, xoff, component_number, data, data.length); 136 } 137 138 private void data1DChecks(int off, int count, int len, int dataSize) { 139 mRS.validate(); 140 if(off < 0) { 141 throw new IllegalArgumentException("Offset must be >= 0."); 142 } 143 if(count < 1) { 144 throw new IllegalArgumentException("Count must be >= 1."); 145 } 146 if((off + count) > mType.getElementCount()) { 147 throw new IllegalArgumentException("Overflow, Available count " + mType.getElementCount() + 148 ", got " + count + " at offset " + off + "."); 149 } 150 if((len) < dataSize) { 151 throw new IllegalArgumentException("Array too small for allocation type."); 152 } 153 } 154 155 public void subData1D(int off, int count, int[] d) { 156 int dataSize = mType.mElement.getSizeBytes() * count; 157 data1DChecks(off, count, d.length * 4, dataSize); 158 mRS.nAllocationSubData1D(mID, off, count, d, dataSize); 159 } 160 public void subData1D(int off, int count, short[] d) { 161 int dataSize = mType.mElement.getSizeBytes() * count; 162 data1DChecks(off, count, d.length * 2, dataSize); 163 mRS.nAllocationSubData1D(mID, off, count, d, dataSize); 164 } 165 public void subData1D(int off, int count, byte[] d) { 166 int dataSize = mType.mElement.getSizeBytes() * count; 167 data1DChecks(off, count, d.length, dataSize); 168 mRS.nAllocationSubData1D(mID, off, count, d, dataSize); 169 } 170 public void subData1D(int off, int count, float[] d) { 171 int dataSize = mType.mElement.getSizeBytes() * count; 172 data1DChecks(off, count, d.length * 4, dataSize); 173 mRS.nAllocationSubData1D(mID, off, count, d, dataSize); 174 } 175 176 177 public void subData2D(int xoff, int yoff, int w, int h, int[] d) { 178 mRS.validate(); 179 mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4); 180 } 181 182 public void subData2D(int xoff, int yoff, int w, int h, float[] d) { 183 mRS.validate(); 184 mRS.nAllocationSubData2D(mID, xoff, yoff, w, h, d, d.length * 4); 185 } 186 187 public void readData(int[] d) { 188 mRS.validate(); 189 mRS.nAllocationRead(mID, d); 190 } 191 192 public void readData(float[] d) { 193 mRS.validate(); 194 mRS.nAllocationRead(mID, d); 195 } 196 197 public synchronized void resize(int dimX) { 198 if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) { 199 throw new IllegalStateException("Resize only support for 1D allocations at this time."); 200 } 201 mRS.nAllocationResize1D(mID, dimX); 202 mRS.finish(); // Necessary because resize is fifoed and update is async. 203 204 int typeID = mRS.nAllocationGetType(mID); 205 mType = new Type(typeID, mRS); 206 mType.updateFromNative(); 207 } 208 209 /* 210 public void resize(int dimX, int dimY) { 211 if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) { 212 throw new IllegalStateException("Resize only support for 2D allocations at this time."); 213 } 214 if (mType.getY() == 0) { 215 throw new IllegalStateException("Resize only support for 2D allocations at this time."); 216 } 217 mRS.nAllocationResize2D(mID, dimX, dimY); 218 } 219 */ 220 221 public class Adapter1D extends BaseObj { 222 Adapter1D(int id, RenderScript rs) { 223 super(id, rs); 224 } 225 226 public void setConstraint(Dimension dim, int value) { 227 mRS.validate(); 228 mRS.nAdapter1DSetConstraint(mID, dim.mID, value); 229 } 230 231 public void data(int[] d) { 232 mRS.validate(); 233 mRS.nAdapter1DData(mID, d); 234 } 235 236 public void data(float[] d) { 237 mRS.validate(); 238 mRS.nAdapter1DData(mID, d); 239 } 240 241 public void subData(int off, int count, int[] d) { 242 mRS.validate(); 243 mRS.nAdapter1DSubData(mID, off, count, d); 244 } 245 246 public void subData(int off, int count, float[] d) { 247 mRS.validate(); 248 mRS.nAdapter1DSubData(mID, off, count, d); 249 } 250 } 251 252 public Adapter1D createAdapter1D() { 253 mRS.validate(); 254 int id = mRS.nAdapter1DCreate(); 255 if(id == 0) { 256 throw new IllegalStateException("allocation failed."); 257 } 258 mRS.nAdapter1DBindAllocation(id, mID); 259 return new Adapter1D(id, mRS); 260 } 261 262 263 public class Adapter2D extends BaseObj { 264 Adapter2D(int id, RenderScript rs) { 265 super(id, rs); 266 } 267 268 public void setConstraint(Dimension dim, int value) { 269 mRS.validate(); 270 mRS.nAdapter2DSetConstraint(mID, dim.mID, value); 271 } 272 273 public void data(int[] d) { 274 mRS.validate(); 275 mRS.nAdapter2DData(mID, d); 276 } 277 278 public void data(float[] d) { 279 mRS.validate(); 280 mRS.nAdapter2DData(mID, d); 281 } 282 283 public void subData(int xoff, int yoff, int w, int h, int[] d) { 284 mRS.validate(); 285 mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d); 286 } 287 288 public void subData(int xoff, int yoff, int w, int h, float[] d) { 289 mRS.validate(); 290 mRS.nAdapter2DSubData(mID, xoff, yoff, w, h, d); 291 } 292 } 293 294 public Adapter2D createAdapter2D() { 295 mRS.validate(); 296 int id = mRS.nAdapter2DCreate(); 297 if(id == 0) { 298 throw new IllegalStateException("allocation failed."); 299 } 300 mRS.nAdapter2DBindAllocation(id, mID); 301 return new Adapter2D(id, mRS); 302 } 303 304 305 // creation 306 307 private static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); 308 static { 309 mBitmapOptions.inScaled = false; 310 } 311 312 static public Allocation createTyped(RenderScript rs, Type type) 313 throws IllegalArgumentException { 314 315 rs.validate(); 316 if(type.mID == 0) { 317 throw new IllegalStateException("Bad Type"); 318 } 319 int id = rs.nAllocationCreateTyped(type.mID); 320 return new Allocation(id, rs, type); 321 } 322 323 static public Allocation createSized(RenderScript rs, Element e, int count) 324 throws IllegalArgumentException { 325 326 rs.validate(); 327 Type.Builder b = new Type.Builder(rs, e); 328 b.add(Dimension.X, count); 329 Type t = b.create(); 330 331 int id = rs.nAllocationCreateTyped(t.mID); 332 if(id == 0) { 333 throw new IllegalStateException("Bad element."); 334 } 335 return new Allocation(id, rs, t); 336 } 337 338 static private Element elementFromBitmap(RenderScript rs, Bitmap b) { 339 final Bitmap.Config bc = b.getConfig(); 340 if (bc == Bitmap.Config.ALPHA_8) { 341 return Element.A_8(rs); 342 } 343 if (bc == Bitmap.Config.ARGB_4444) { 344 return Element.RGBA_4444(rs); 345 } 346 if (bc == Bitmap.Config.ARGB_8888) { 347 return Element.RGBA_8888(rs); 348 } 349 if (bc == Bitmap.Config.RGB_565) { 350 return Element.RGB_565(rs); 351 } 352 throw new IllegalStateException("Bad bitmap type."); 353 } 354 355 static private Type typeFromBitmap(RenderScript rs, Bitmap b) { 356 Element e = elementFromBitmap(rs, b); 357 Type.Builder tb = new Type.Builder(rs, e); 358 tb.add(Dimension.X, b.getWidth()); 359 tb.add(Dimension.Y, b.getHeight()); 360 return tb.create(); 361 } 362 363 static public Allocation createFromBitmap(RenderScript rs, Bitmap b, Element dstFmt, boolean genMips) 364 throws IllegalArgumentException { 365 366 rs.validate(); 367 Type t = typeFromBitmap(rs, b); 368 369 int id = rs.nAllocationCreateFromBitmap(dstFmt.mID, genMips, b); 370 if(id == 0) { 371 throw new IllegalStateException("Load failed."); 372 } 373 return new Allocation(id, rs, t); 374 } 375 376 static public Allocation createBitmapRef(RenderScript rs, Bitmap b) 377 throws IllegalArgumentException { 378 379 rs.validate(); 380 Type t = typeFromBitmap(rs, b); 381 382 int id = rs.nAllocationCreateBitmapRef(t.getID(), b); 383 if(id == 0) { 384 throw new IllegalStateException("Load failed."); 385 } 386 387 Allocation a = new Allocation(id, rs, t); 388 a.mBitmap = b; 389 return a; 390 } 391 392 static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips) 393 throws IllegalArgumentException { 394 395 rs.validate(); 396 InputStream is = null; 397 try { 398 final TypedValue value = new TypedValue(); 399 is = res.openRawResource(id, value); 400 401 int asset = ((AssetManager.AssetInputStream) is).getAssetInt(); 402 int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mID, genMips, 403 asset); 404 405 if(allocationId == 0) { 406 throw new IllegalStateException("Load failed."); 407 } 408 return new Allocation(allocationId, rs, null); 409 } catch (Exception e) { 410 // Ignore 411 } finally { 412 if (is != null) { 413 try { 414 is.close(); 415 } catch (IOException e) { 416 // Ignore 417 } 418 } 419 } 420 421 return null; 422 } 423 424 static public Allocation createFromString(RenderScript rs, String str) 425 throws IllegalArgumentException { 426 byte[] allocArray = null; 427 try { 428 allocArray = str.getBytes("UTF-8"); 429 Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length); 430 alloc.data(allocArray); 431 return alloc; 432 } 433 catch (Exception e) { 434 Log.e("rs", "could not convert string to utf-8"); 435 } 436 return null; 437 } 438} 439 440 441