summaryrefslogtreecommitdiff
path: root/rsGrallocConsumer.cpp
diff options
context:
space:
mode:
authorMiao Wang <miaowang@google.com>2015-10-26 16:50:13 -0700
committerMiao Wang <miaowang@google.com>2016-01-26 21:45:28 -0800
commit754746883bd46ec2fbdd23572cb6c90ab589346c (patch)
tree25ee78a9709bffd7437fc6d7856d6efe67d5e0cc /rsGrallocConsumer.cpp
parentf7e0c7cf9bae9cf0e9f8943b24639712fd85bcba (diff)
downloadrs-754746883bd46ec2fbdd23572cb6c90ab589346c.tar.gz
Add multi-frame support to RenderScript:
Bug: 23535524 - Allow multi-consumer for a single BufferQueue with specifying the the number of buffers need. - Allow USAGE_IO_INPUT allocations share the same BufferQueue with an existing Allocation. - Individual allocations can still call ioReceive independently - Add getTimeStamp() for multi-frame processing. Change-Id: Ia8f48f5fc50d578c68306bb32f0eac9636f5f32a
Diffstat (limited to 'rsGrallocConsumer.cpp')
-rw-r--r--rsGrallocConsumer.cpp127
1 files changed, 91 insertions, 36 deletions
diff --git a/rsGrallocConsumer.cpp b/rsGrallocConsumer.cpp
index 3e613204..4d3c5dd3 100644
--- a/rsGrallocConsumer.cpp
+++ b/rsGrallocConsumer.cpp
@@ -30,17 +30,23 @@
namespace android {
namespace renderscript {
-GrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq, int flags) :
+GrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq, int flags, uint32_t numAlloc) :
ConsumerBase(bq, true)
{
- mAlloc = a;
+ mAlloc = new Allocation *[numAlloc];
+ mAcquiredBuffer = new AcquiredBuffer[numAlloc];
+ isIdxUsed = new bool[numAlloc];
+
+ mAlloc[0] = a;
+ isIdxUsed[0] = true;
+ mNumAlloc = numAlloc;
if (flags == 0) {
flags = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_RENDERSCRIPT;
} else {
flags |= GRALLOC_USAGE_RENDERSCRIPT;
}
mConsumer->setConsumerUsageBits(flags);
- mConsumer->setMaxAcquiredBufferCount(2);
+ mConsumer->setMaxAcquiredBufferCount(numAlloc + 1);
uint32_t y = a->mHal.drvState.lod[0].dimY;
if (y < 1) y = 1;
@@ -49,21 +55,31 @@ GrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>
if (a->mHal.state.yuv) {
bq->setDefaultBufferFormat(a->mHal.state.yuv);
}
+ for (uint32_t i = 1; i < numAlloc; i++) {
+ isIdxUsed[i] = false;
+ }
//mBufferQueue->setConsumerName(name);
}
GrallocConsumer::~GrallocConsumer() {
- // ConsumerBase destructor does all the work.
+ delete[] mAlloc;
+ delete[] mAcquiredBuffer;
+ delete[] isIdxUsed;
}
-status_t GrallocConsumer::lockNextBuffer() {
+status_t GrallocConsumer::lockNextBuffer(uint32_t idx) {
Mutex::Autolock _l(mMutex);
status_t err;
- if (mAcquiredBuffer.mSlot != BufferQueue::INVALID_BUFFER_SLOT) {
- err = releaseAcquiredBufferLocked();
+ if (idx >= mNumAlloc) {
+ ALOGE("Invalid buffer index: %d", idx);
+ return BAD_VALUE;
+ }
+
+ if (mAcquiredBuffer[idx].mSlot != BufferQueue::INVALID_BUFFER_SLOT) {
+ err = releaseAcquiredBufferLocked(idx);
if (err) {
return err;
}
@@ -122,21 +138,21 @@ status_t GrallocConsumer::lockNextBuffer() {
}
size_t lockedIdx = 0;
- rsAssert(mAcquiredBuffer.mSlot == BufferQueue::INVALID_BUFFER_SLOT);
+ rsAssert(mAcquiredBuffer[idx].mSlot == BufferQueue::INVALID_BUFFER_SLOT);
- mAcquiredBuffer.mSlot = buf;
- mAcquiredBuffer.mBufferPointer = bufferPointer;
- mAcquiredBuffer.mGraphicBuffer = mSlots[buf].mGraphicBuffer;
+ mAcquiredBuffer[idx].mSlot = buf;
+ mAcquiredBuffer[idx].mBufferPointer = bufferPointer;
+ mAcquiredBuffer[idx].mGraphicBuffer = mSlots[buf].mGraphicBuffer;
- mAlloc->mHal.drvState.lod[0].mallocPtr = reinterpret_cast<uint8_t*>(bufferPointer);
- mAlloc->mHal.drvState.lod[0].stride = mSlots[buf].mGraphicBuffer->getStride() *
- mAlloc->mHal.state.type->getElementSizeBytes();
- mAlloc->mHal.state.nativeBuffer = mAcquiredBuffer.mGraphicBuffer->getNativeBuffer();
- mAlloc->mHal.state.timestamp = b.mTimestamp;
+ mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = reinterpret_cast<uint8_t*>(bufferPointer);
+ mAlloc[idx]->mHal.drvState.lod[0].stride = mSlots[buf].mGraphicBuffer->getStride() *
+ mAlloc[idx]->mHal.state.type->getElementSizeBytes();
+ mAlloc[idx]->mHal.state.nativeBuffer = mAcquiredBuffer[idx].mGraphicBuffer->getNativeBuffer();
+ mAlloc[idx]->mHal.state.timestamp = b.mTimestamp;
- rsAssert(mAlloc->mHal.drvState.lod[0].dimX ==
+ rsAssert(mAlloc[idx]->mHal.drvState.lod[0].dimX ==
mSlots[buf].mGraphicBuffer->getWidth());
- rsAssert(mAlloc->mHal.drvState.lod[0].dimY ==
+ rsAssert(mAlloc[idx]->mHal.drvState.lod[0].dimY ==
mSlots[buf].mGraphicBuffer->getHeight());
//mAlloc->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
@@ -146,51 +162,90 @@ status_t GrallocConsumer::lockNextBuffer() {
//mAlloc->scalingMode = b.mScalingMode;
//mAlloc->frameNumber = b.mFrameNumber;
- if (mAlloc->mHal.state.yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- mAlloc->mHal.drvState.lod[1].mallocPtr = ycbcr.cb;
- mAlloc->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
+ if (mAlloc[idx]->mHal.state.yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = ycbcr.cb;
+ mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
- mAlloc->mHal.drvState.lod[0].stride = ycbcr.ystride;
- mAlloc->mHal.drvState.lod[1].stride = ycbcr.cstride;
- mAlloc->mHal.drvState.lod[2].stride = ycbcr.cstride;
+ mAlloc[idx]->mHal.drvState.lod[0].stride = ycbcr.ystride;
+ mAlloc[idx]->mHal.drvState.lod[1].stride = ycbcr.cstride;
+ mAlloc[idx]->mHal.drvState.lod[2].stride = ycbcr.cstride;
- mAlloc->mHal.drvState.yuv.shift = 1;
- mAlloc->mHal.drvState.yuv.step = ycbcr.chroma_step;
+ mAlloc[idx]->mHal.drvState.yuv.shift = 1;
+ mAlloc[idx]->mHal.drvState.yuv.step = ycbcr.chroma_step;
}
return OK;
}
-status_t GrallocConsumer::unlockBuffer() {
+status_t GrallocConsumer::unlockBuffer(uint32_t idx) {
Mutex::Autolock _l(mMutex);
- return releaseAcquiredBufferLocked();
+ return releaseAcquiredBufferLocked(idx);
}
-status_t GrallocConsumer::releaseAcquiredBufferLocked() {
+status_t GrallocConsumer::releaseAcquiredBufferLocked(uint32_t idx) {
status_t err;
- err = mAcquiredBuffer.mGraphicBuffer->unlock();
+ if (idx >= mNumAlloc) {
+ ALOGE("Invalid buffer index: %d", idx);
+ return BAD_VALUE;
+ }
+ if (mAcquiredBuffer[idx].mGraphicBuffer == nullptr) {
+ return OK;
+ }
+
+ err = mAcquiredBuffer[idx].mGraphicBuffer->unlock();
if (err != OK) {
ALOGE("%s: Unable to unlock graphic buffer", __FUNCTION__);
return err;
}
- int buf = mAcquiredBuffer.mSlot;
+ int buf = mAcquiredBuffer[idx].mSlot;
// release the buffer if it hasn't already been freed by the BufferQueue.
// This can happen, for example, when the producer of this buffer
// disconnected after this buffer was acquired.
- if (CC_LIKELY(mAcquiredBuffer.mGraphicBuffer ==
+ if (CC_LIKELY(mAcquiredBuffer[idx].mGraphicBuffer ==
mSlots[buf].mGraphicBuffer)) {
releaseBufferLocked(
- buf, mAcquiredBuffer.mGraphicBuffer,
+ buf, mAcquiredBuffer[idx].mGraphicBuffer,
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
}
- mAcquiredBuffer.mSlot = BufferQueue::INVALID_BUFFER_SLOT;
- mAcquiredBuffer.mBufferPointer = nullptr;
- mAcquiredBuffer.mGraphicBuffer.clear();
+ mAcquiredBuffer[idx].mSlot = BufferQueue::INVALID_BUFFER_SLOT;
+ mAcquiredBuffer[idx].mBufferPointer = nullptr;
+ mAcquiredBuffer[idx].mGraphicBuffer.clear();
return OK;
}
+uint32_t GrallocConsumer::getNextAvailableIdx(Allocation *a) {
+ for (uint32_t i = 0; i < mNumAlloc; i++) {
+ if (isIdxUsed[i] == false) {
+ mAlloc[i] = a;
+ isIdxUsed[i] = true;
+ return i;
+ }
+ }
+ return mNumAlloc;
+}
+
+bool GrallocConsumer::releaseIdx(uint32_t idx) {
+ if (idx >= mNumAlloc) {
+ ALOGE("Invalid buffer index: %d", idx);
+ return false;
+ }
+ if (isIdxUsed[idx] == false) {
+ ALOGV("Buffer index already released: %d", idx);
+ return true;
+ }
+ status_t err;
+ err = unlockBuffer(idx);
+ if (err != OK) {
+ ALOGE("Unable to unlock graphic buffer");
+ return false;
+ }
+ mAlloc[idx] = nullptr;
+ isIdxUsed[idx] = false;
+ return true;
+}
+
} // namespace renderscript
} // namespace android