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