1 /* 2 * Copyright (C) 2011 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 17 18 package android.filterfw.core; 19 20 import android.filterfw.core.Frame; 21 22 /** 23 * @hide 24 */ 25 public class NativeBuffer { 26 27 // These are set by the native layer 28 private long mDataPointer = 0; 29 private int mSize = 0; 30 31 private Frame mAttachedFrame; 32 33 private boolean mOwnsData = false; 34 private int mRefCount = 1; 35 NativeBuffer()36 public NativeBuffer() { 37 } 38 NativeBuffer(int count)39 public NativeBuffer(int count) { 40 allocate(count * getElementSize()); 41 mOwnsData = true; 42 } 43 mutableCopy()44 public NativeBuffer mutableCopy() { 45 NativeBuffer result = null; 46 try { 47 Class myClass = getClass(); 48 result = (NativeBuffer)myClass.newInstance(); 49 } catch (Exception e) { 50 throw new RuntimeException("Unable to allocate a copy of " + getClass() + "! Make " + 51 "sure the class has a default constructor!"); 52 } 53 if (mSize > 0 && !nativeCopyTo(result)) { 54 throw new RuntimeException("Failed to copy NativeBuffer to mutable instance!"); 55 } 56 return result; 57 } 58 size()59 public int size() { 60 return mSize; 61 } 62 count()63 public int count() { 64 return (mDataPointer != 0) ? mSize / getElementSize() : 0; 65 } 66 getElementSize()67 public int getElementSize() { 68 return 1; 69 } 70 retain()71 public NativeBuffer retain() { 72 if (mAttachedFrame != null) { 73 mAttachedFrame.retain(); 74 } else if (mOwnsData) { 75 ++mRefCount; 76 } 77 return this; 78 } 79 release()80 public NativeBuffer release() { 81 // Decrement refcount 82 boolean doDealloc = false; 83 if (mAttachedFrame != null) { 84 doDealloc = (mAttachedFrame.release() == null); 85 } else if (mOwnsData) { 86 --mRefCount; 87 doDealloc = (mRefCount == 0); 88 } 89 90 // Deallocate if necessary 91 if (doDealloc) { 92 deallocate(mOwnsData); 93 return null; 94 } else { 95 return this; 96 } 97 } 98 isReadOnly()99 public boolean isReadOnly() { 100 return (mAttachedFrame != null) ? mAttachedFrame.isReadOnly() : false; 101 } 102 103 static { 104 System.loadLibrary("filterfw"); 105 } 106 attachToFrame(Frame frame)107 void attachToFrame(Frame frame) { 108 // We do not auto-retain. We expect the user to call retain() if they want to hold on to 109 // the frame. 110 mAttachedFrame = frame; 111 } 112 assertReadable()113 protected void assertReadable() { 114 if (mDataPointer == 0 || mSize == 0 115 || (mAttachedFrame != null && !mAttachedFrame.hasNativeAllocation())) { 116 throw new NullPointerException("Attempting to read from null data frame!"); 117 } 118 } 119 assertWritable()120 protected void assertWritable() { 121 if (isReadOnly()) { 122 throw new RuntimeException("Attempting to modify read-only native (structured) data!"); 123 } 124 } 125 allocate(int size)126 private native boolean allocate(int size); deallocate(boolean ownsData)127 private native boolean deallocate(boolean ownsData); nativeCopyTo(NativeBuffer buffer)128 private native boolean nativeCopyTo(NativeBuffer buffer); 129 } 130