18f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown/* 28f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Copyright (C) 2013 The Android Open Source Project 38f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * 48f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 58f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * you may not use this file except in compliance with the License. 68f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * You may obtain a copy of the License at 78f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * 88f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 98f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * 108f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Unless required by applicable law or agreed to in writing, software 118f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 128f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * See the License for the specific language governing permissions and 148f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * limitations under the License. 158f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown */ 168f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 178f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownpackage com.android.accessorydisplay.common; 188f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 198f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownimport java.nio.ByteBuffer; 208f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 218f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown/** 228f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Maintains a bounded pool of buffers. Attempts to acquire buffers beyond the maximum 238f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * count will block until other buffers are released. 248f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown */ 258f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownfinal class BufferPool { 268f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown private final int mInitialBufferSize; 278f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown private final int mMaxBufferSize; 288f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown private final ByteBuffer[] mBuffers; 298f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown private int mAllocated; 308f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown private int mAvailable; 318f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 328f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown public BufferPool(int initialBufferSize, int maxBufferSize, int maxBuffers) { 338f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown mInitialBufferSize = initialBufferSize; 348f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown mMaxBufferSize = maxBufferSize; 358f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown mBuffers = new ByteBuffer[maxBuffers]; 368f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 378f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 388f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown public ByteBuffer acquire(int needed) { 398f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown synchronized (this) { 408f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown for (;;) { 418f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown if (mAvailable != 0) { 428f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown mAvailable -= 1; 438f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown return grow(mBuffers[mAvailable], needed); 448f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 458f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 468f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown if (mAllocated < mBuffers.length) { 478f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown mAllocated += 1; 488f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown return ByteBuffer.allocate(chooseCapacity(mInitialBufferSize, needed)); 498f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 508f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 518f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown try { 528f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown wait(); 538f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } catch (InterruptedException ex) { 548f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 558f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 568f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 578f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 588f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 598f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown public void release(ByteBuffer buffer) { 608f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown synchronized (this) { 618f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown buffer.clear(); 628f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown mBuffers[mAvailable++] = buffer; 638f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown notifyAll(); 648f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 658f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 668f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 678f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown public ByteBuffer grow(ByteBuffer buffer, int needed) { 688f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown int capacity = buffer.capacity(); 698f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown if (capacity < needed) { 708f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown final ByteBuffer oldBuffer = buffer; 718f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown capacity = chooseCapacity(capacity, needed); 728f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown buffer = ByteBuffer.allocate(capacity); 738f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown oldBuffer.flip(); 748f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown buffer.put(oldBuffer); 758f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 768f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown return buffer; 778f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 788f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown 798f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown private int chooseCapacity(int capacity, int needed) { 808f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown while (capacity < needed) { 818f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown capacity *= 2; 828f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 838f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown if (capacity > mMaxBufferSize) { 848f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown if (needed > mMaxBufferSize) { 858f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown throw new IllegalArgumentException("Requested size " + needed 868f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown + " is larger than maximum buffer size " + mMaxBufferSize + "."); 878f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 888f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown capacity = mMaxBufferSize; 898f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 908f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown return capacity; 918f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown } 928f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown} 93