Merge changes from topics 'USAGE_IO_INPUT', 'USAGE_IO_OUTPUT'
* changes:
Update C++ API (libRSCpp.so) with the corresponding AllocationGetSurface driver implementation change
Implement USAGE_IO_INPUT related functions on top of NDK.
Implement USAGE_IO_OUTPUT related methods on top of NDK.
diff --git a/Android.mk b/Android.mk
index 7c32525..3e5f593 100644
--- a/Android.mk
+++ b/Android.mk
@@ -64,7 +64,7 @@
LOCAL_SHARED_LIBRARIES += libRS_internal libRSCpuRef
LOCAL_SHARED_LIBRARIES += liblog libutils libEGL libGLESv1_CM libGLESv2
-LOCAL_SHARED_LIBRARIES += libui libgui
+LOCAL_SHARED_LIBRARIES += libui libgui libandroid
LOCAL_SHARED_LIBRARIES += libbcinfo
@@ -188,7 +188,9 @@
LOCAL_SHARED_LIBRARIES += libdl libgui libui
LOCAL_SHARED_LIBRARIES += libft2 libpng
-LOCAL_SHARED_LIBRARIES += libbcinfo
+LOCAL_SHARED_LIBRARIES += libbcinfo libmediandk
+
+LOCAL_C_INCLUDES += frameworks/av/include/ndk
LOCAL_CFLAGS += $(rs_base_CFLAGS)
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp
index 12dad8f..2f5ca64 100644
--- a/cpp/Allocation.cpp
+++ b/cpp/Allocation.cpp
@@ -501,12 +501,10 @@
mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Can only get Surface if IO_INPUT usage specified.");
return nullptr;
}
- IGraphicBufferProducer *v = (IGraphicBufferProducer *)RS::dispatch->AllocationGetSurface(mRS->getContext(),
- getID());
- android::sp<IGraphicBufferProducer> bp = v;
- v->decStrong(nullptr);
-
- return new Surface(bp, true);;
+ ANativeWindow *anw = (ANativeWindow *)RS::dispatch->AllocationGetSurface(mRS->getContext(),
+ getID());
+ sp<Surface> surface(static_cast<Surface*>(anw));
+ return surface;
}
void Allocation::setSurface(const sp<Surface>& s) {
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 249daa5..0381715 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -14,16 +14,10 @@
* limitations under the License.
*/
-#include "rsdCore.h"
#include "rsdAllocation.h"
+#include "rsdCore.h"
-#include "rsAllocation.h"
-
-#ifndef RS_COMPATIBILITY_LIB
-#include "system/window.h"
-#include "ui/Rect.h"
-#include "ui/GraphicBufferMapper.h"
-#endif
+#include <android/native_window.h>
#ifdef RS_COMPATIBILITY_LIB
#include "rsCompatibilityLib.h"
@@ -39,12 +33,6 @@
#include <GLES/glext.h>
#endif
-#ifndef RS_COMPATIBILITY_LIB
-using android::GraphicBufferMapper;
-using android::PIXEL_FORMAT_RGBA_8888;
-using android::Rect;
-#endif
-
using android::renderscript::Allocation;
using android::renderscript::Context;
using android::renderscript::Element;
@@ -582,17 +570,13 @@
if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
-
- DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
ANativeWindow *nw = drv->wndSurface;
if (nw) {
- GraphicBufferMapper &mapper = GraphicBufferMapper::get();
- mapper.unlock(drv->wndBuffer->handle);
- int32_t r = nw->cancelBuffer(nw, drv->wndBuffer, -1);
-
+ //If we have an attached surface, need to release it.
+ ANativeWindow_unlockAndPost(nw);
+ ANativeWindow_release(nw);
drv->wndSurface = nullptr;
- native_window_api_disconnect(nw, NATIVE_WINDOW_API_CPU);
- nw->decStrong(nullptr);
+ delete drv->wndBuffer;
}
}
#endif
@@ -717,21 +701,17 @@
#ifndef RS_COMPATIBILITY_LIB
static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
-
- int32_t r = native_window_dequeue_buffer_and_wait(nw, &drv->wndBuffer);
+ // Must lock the whole surface
+ if(drv->wndBuffer == nullptr) {
+ drv->wndBuffer = new ANativeWindow_Buffer;
+ }
+ int32_t r = ANativeWindow_lock(nw, drv->wndBuffer, NULL);
if (r) {
- rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
+ rsc->setError(RS_ERROR_DRIVER, "Error Locking IO output buffer.");
return false;
}
- // Must lock the whole surface
- GraphicBufferMapper &mapper = GraphicBufferMapper::get();
- Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
-
- void *dst = nullptr;
- mapper.lock(drv->wndBuffer->handle,
- GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
- bounds, &dst);
+ void *dst = drv->wndBuffer->bits;
alloc->mHal.drvState.lod[0].mallocPtr = dst;
alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
rsAssert((alloc->mHal.drvState.lod[0].stride & 0xf) == 0);
@@ -743,75 +723,23 @@
void rsdAllocationSetSurface(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
#ifndef RS_COMPATIBILITY_LIB
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
- ANativeWindow *old = drv->wndSurface;
-
- if (nw) {
- nw->incStrong(nullptr);
- }
-
- if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
- //TODO finish support for render target + script
- drv->wnd = nw;
- return;
- }
// Cleanup old surface if there is one.
if (drv->wndSurface) {
ANativeWindow *old = drv->wndSurface;
- GraphicBufferMapper &mapper = GraphicBufferMapper::get();
- mapper.unlock(drv->wndBuffer->handle);
- old->cancelBuffer(old, drv->wndBuffer, -1);
+ ANativeWindow_unlockAndPost(old);
+ ANativeWindow_release(old);
drv->wndSurface = nullptr;
-
- native_window_api_disconnect(old, NATIVE_WINDOW_API_CPU);
- old->decStrong(nullptr);
}
- if (nw != nullptr) {
+ if (nw) {
int32_t r;
- uint32_t flags = 0;
-
- if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
- flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
- }
- if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
- flags |= GRALLOC_USAGE_HW_RENDER;
- }
-
- r = native_window_api_connect(nw, NATIVE_WINDOW_API_CPU);
+ r = ANativeWindow_setBuffersGeometry(nw, alloc->mHal.drvState.lod[0].dimX,
+ alloc->mHal.drvState.lod[0].dimY,
+ WINDOW_FORMAT_RGBA_8888);
if (r) {
- rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
- goto error;
- }
-
- r = native_window_set_usage(nw, flags);
- if (r) {
- rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
- goto error;
- }
-
- r = native_window_set_buffers_dimensions(nw, alloc->mHal.drvState.lod[0].dimX,
- alloc->mHal.drvState.lod[0].dimY);
- if (r) {
- rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
- goto error;
- }
-
- int format = 0;
- const Element *e = alloc->mHal.state.type->getElement();
- if ((e->getType() != RS_TYPE_UNSIGNED_8) ||
- (e->getVectorSize() != 4)) {
- // We do not check for RGBA, RGBx, to allow for interop with U8_4
-
- rsc->setError(RS_ERROR_DRIVER, "Surface passed to setSurface is not U8_4, RGBA.");
- goto error;
- }
- format = PIXEL_FORMAT_RGBA_8888;
-
- r = native_window_set_buffers_format(nw, format);
- if (r) {
- rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer format.");
- goto error;
+ rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer geometry.");
+ return;
}
IoGetBuffer(rsc, alloc, nw);
@@ -819,14 +747,6 @@
}
return;
-
- error:
-
- if (nw) {
- nw->decStrong(nullptr);
- }
-
-
#endif
}
@@ -841,14 +761,11 @@
}
if (nw) {
if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
- GraphicBufferMapper &mapper = GraphicBufferMapper::get();
- mapper.unlock(drv->wndBuffer->handle);
- int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
+ int32_t r = ANativeWindow_unlockAndPost(nw);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
return;
}
-
IoGetBuffer(rsc, alloc, nw);
}
} else {
diff --git a/driver/rsdAllocation.h b/driver/rsdAllocation.h
index ec31aed..c2d1467 100644
--- a/driver/rsdAllocation.h
+++ b/driver/rsdAllocation.h
@@ -53,15 +53,14 @@
GLenum glType;
GLenum glFormat;
- ANativeWindowBuffer *wndBuffer;
android::GLConsumer *surfaceTexture;
#else
int glTarget;
int glType;
int glFormat;
+#endif
ANativeWindow_Buffer *wndBuffer;
-#endif
bool useUserProvidedPtr;
bool uploadDeferred;
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index 980850c..59944bf 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -18,6 +18,10 @@
#include "rsAllocation.h"
#include "rs_hal.h"
+#ifndef RS_COMPATIBILITY_LIB
+#include "rsGrallocConsumer.h"
+#endif
+
namespace android {
namespace renderscript {
@@ -148,8 +152,11 @@
Allocation::~Allocation() {
#ifndef RS_COMPATIBILITY_LIB
- if (mGrallocConsumer.get()) {
+ if (mGrallocConsumer) {
mGrallocConsumer->releaseIdx(mCurrentIdx);
+ if (!mGrallocConsumer->isActive()) {
+ delete mGrallocConsumer;
+ }
mGrallocConsumer = nullptr;
}
#endif
@@ -569,29 +576,6 @@
rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented");
}
-#ifndef RS_COMPATIBILITY_LIB
-Allocation::NewBufferListener::NewBufferListener(uint32_t numAlloc) {
- alloc = new const Allocation *[numAlloc];
- mNumAlloc = numAlloc;
- for (uint32_t i = 0; i < numAlloc; i++) {
- alloc[i] = nullptr;
- }
-}
-
-Allocation::NewBufferListener::~NewBufferListener() {
- delete[] alloc;
-}
-
-void Allocation::NewBufferListener::onFrameAvailable(const BufferItem& /* item */) {
- for (uint32_t i = 0; i < mNumAlloc; i++) {
- if (alloc[i] != nullptr) {
- intptr_t ip = (intptr_t)alloc[i];
- rsc->sendMessageToClient(&ip, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true);
- }
- }
-}
-#endif
-
void Allocation::setupGrallocConsumer(const Context *rsc, uint32_t numAlloc) {
#ifndef RS_COMPATIBILITY_LIB
// Configure GrallocConsumer to be in asynchronous mode
@@ -599,17 +583,9 @@
rsc->setError(RS_ERROR_FATAL_DRIVER, "resize2d not implemented");
return;
}
- sp<IGraphicBufferConsumer> bc;
- BufferQueue::createBufferQueue(&mGraphicBufferProducer, &bc);
- mGrallocConsumer = new GrallocConsumer(this, bc, mHal.drvState.grallocFlags, numAlloc);
-
- mBufferListener = new NewBufferListener(numAlloc);
- mBufferListener->rsc = rsc;
- mBufferListener->alloc[0] = this;
+ mGrallocConsumer = new GrallocConsumer(rsc, this, numAlloc);
mCurrentIdx = 0;
mBufferQueueInited = true;
-
- mGrallocConsumer->setFrameAvailableListener(mBufferListener);
#endif
}
@@ -622,12 +598,10 @@
// multi-frame case.
setupGrallocConsumer(rsc, 1);
}
- mGraphicBufferProducer->incStrong(nullptr);
- return mGraphicBufferProducer.get();
+ return mGrallocConsumer->getNativeWindow();
#else
return nullptr;
#endif
- //return rsc->mHal.funcs.allocation.getSurface(rsc, this);
}
void Allocation::shareBufferQueue(const Context *rsc, const Allocation *alloc) {
@@ -638,10 +612,6 @@
rsc->setError(RS_ERROR_DRIVER, "Maximum allocations attached to a BufferQueue");
return;
}
-
- mGraphicBufferProducer = alloc->mGraphicBufferProducer;
- mBufferListener = alloc->mBufferListener;
- mBufferListener->alloc[mCurrentIdx] = this;
mBufferQueueInited = true;
#endif
}
@@ -661,11 +631,11 @@
size_t stride = 0;
#ifndef RS_COMPATIBILITY_LIB
if (mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
- status_t ret = mGrallocConsumer->lockNextBuffer(mCurrentIdx);
+ media_status_t ret = mGrallocConsumer->lockNextBuffer(mCurrentIdx);
- if (ret == OK) {
+ if (ret == AMEDIA_OK) {
rsc->mHal.funcs.allocation.ioReceive(rsc, this);
- } else if (ret == BAD_VALUE) {
+ } else if (ret == AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE) {
// No new frame, don't do anything
} else {
rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer.");
diff --git a/rsAllocation.h b/rsAllocation.h
index f6a1283..60f17a3 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -20,7 +20,6 @@
#include "rsType.h"
#ifndef RS_COMPATIBILITY_LIB
-#include "rsGrallocConsumer.h"
#include "gui/CpuConsumer.h"
#include "gui/GLConsumer.h"
#else
@@ -33,6 +32,7 @@
namespace renderscript {
class Program;
+class GrallocConsumer;
/*****************************************************************************
* CAUTION
@@ -220,21 +220,7 @@
}
#ifndef RS_COMPATIBILITY_LIB
- class NewBufferListener : public android::ConsumerBase::FrameAvailableListener {
- public:
- explicit NewBufferListener(uint32_t numAlloc);
- virtual ~NewBufferListener();
- const android::renderscript::Context *rsc;
- const android::renderscript::Allocation **alloc;
-
- virtual void onFrameAvailable(const BufferItem& item);
- private:
- uint32_t mNumAlloc;
- };
-
- sp<NewBufferListener> mBufferListener;
- sp< GrallocConsumer > mGrallocConsumer;
- sp<IGraphicBufferProducer> mGraphicBufferProducer;
+ GrallocConsumer *mGrallocConsumer = nullptr;
bool mBufferQueueInited = false;
uint32_t mCurrentIdx;
#endif
diff --git a/rsGrallocConsumer.cpp b/rsGrallocConsumer.cpp
index 77bffa5..67ab9d0 100644
--- a/rsGrallocConsumer.cpp
+++ b/rsGrallocConsumer.cpp
@@ -14,24 +14,17 @@
* limitations under the License.
*/
-#define ATRACE_TAG ATRACE_TAG_RS
-
-#include "rsContext.h"
#include "rsAllocation.h"
-#include "rs_hal.h"
-
-#include <utils/Log.h>
+#include "rsContext.h"
#include "rsGrallocConsumer.h"
-#include <gui/BufferItem.h>
-#include <ui/GraphicBuffer.h>
-
+#include "rs_hal.h"
namespace android {
namespace renderscript {
-GrallocConsumer::GrallocConsumer(Allocation *a, const sp<IGraphicBufferConsumer>& bq, int flags, uint32_t numAlloc) :
- ConsumerBase(bq, true)
+GrallocConsumer::GrallocConsumer (const Context *rsc, Allocation *a, uint32_t numAlloc)
{
+ mCtx = rsc;
mAlloc = new Allocation *[numAlloc];
mAcquiredBuffer = new AcquiredBuffer[numAlloc];
isIdxUsed = new bool[numAlloc];
@@ -39,236 +32,207 @@
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(numAlloc + 1);
- uint32_t y = a->mHal.drvState.lod[0].dimY;
- if (y < 1) y = 1;
- mConsumer->setDefaultBufferSize(a->mHal.drvState.lod[0].dimX, y);
+ uint32_t width = a->mHal.drvState.lod[0].dimX;
+ uint32_t height = a->mHal.drvState.lod[0].dimY;
+ if (height < 1) height = 1;
+ int32_t format = AIMAGE_FORMAT_RGBA_8888;
if (a->mHal.state.yuv) {
- bq->setDefaultBufferFormat(a->mHal.state.yuv);
+ format = AIMAGE_FORMAT_YUV_420_888;
}
+
+ media_status_t ret = AImageReader_new(
+ width, height, format,
+ mNumAlloc, &mImgReader);
+ if (ret != AMEDIA_OK || mImgReader == nullptr) {
+ ALOGE("Error creating image reader. ret %d", ret);
+ }
+
+ ret = AImageReader_getWindow(mImgReader, &mNativeWindow);
+ if (ret != AMEDIA_OK || mNativeWindow == nullptr) {
+ ALOGE("Error creating native window. ret %d", ret);
+ }
+
+ mReaderCb = {this, GrallocConsumer::onFrameAvailable};
+ ret = AImageReader_setImageListener(mImgReader, &mReaderCb);
+
for (uint32_t i = 1; i < numAlloc; i++) {
isIdxUsed[i] = false;
}
- //mBufferQueue->setConsumerName(name);
}
GrallocConsumer::~GrallocConsumer() {
+ AImageReader_delete(mImgReader);
delete[] mAlloc;
delete[] mAcquiredBuffer;
delete[] isIdxUsed;
}
+void GrallocConsumer::onFrameAvailable(void* obj, AImageReader* reader) {
+ GrallocConsumer* consumer = (GrallocConsumer *) obj;
+ for (uint32_t i = 0; i < consumer->mNumAlloc; i++) {
+ if (consumer->mAlloc[i] != nullptr) {
+ intptr_t ip = (intptr_t)(consumer->mAlloc[i]);
+ consumer->mCtx->sendMessageToClient(&ip,
+ RS_MESSAGE_TO_CLIENT_NEW_BUFFER, 0, sizeof(ip), true);
+ }
+ }
+}
+ANativeWindow* GrallocConsumer::getNativeWindow() {
+ return mNativeWindow;
+}
-status_t GrallocConsumer::lockNextBuffer(uint32_t idx) {
- Mutex::Autolock _l(mMutex);
- status_t err;
+media_status_t GrallocConsumer::lockNextBuffer(uint32_t idx) {
+ media_status_t ret;
if (idx >= mNumAlloc) {
ALOGE("Invalid buffer index: %d", idx);
- return BAD_VALUE;
+ return AMEDIA_ERROR_INVALID_PARAMETER;
}
- if (mAcquiredBuffer[idx].mSlot != BufferQueue::INVALID_BUFFER_SLOT) {
- err = releaseAcquiredBufferLocked(idx);
- if (err) {
- return err;
+ if (mAcquiredBuffer[idx].mImg != nullptr) {
+ ret = unlockBuffer(idx);
+ if (ret != AMEDIA_OK) {
+ return ret;
}
}
- BufferItem b;
-
- err = acquireBufferLocked(&b, 0);
- if (err != OK) {
- if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
- return BAD_VALUE;
- } else {
- ALOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
- return err;
- }
+ ret = AImageReader_acquireNextImage(mImgReader, &(mAcquiredBuffer[idx].mImg));
+ if (ret != AMEDIA_OK || mAcquiredBuffer[idx].mImg == nullptr) {
+ ALOGE("%s: acquire image from reader %p failed! ret: %d, img %p",
+ __FUNCTION__, mImgReader, ret, mAcquiredBuffer[idx].mImg);
+ return ret;
}
- int slot = b.mSlot;
-
- if (b.mFence.get()) {
- err = b.mFence->waitForever("GrallocConsumer::lockNextBuffer");
- if (err != OK) {
- ALOGE("Failed to wait for fence of acquired buffer: %s (%d)",
- strerror(-err), err);
- return err;
- }
+ AImage *img = mAcquiredBuffer[idx].mImg;
+ int32_t format = -1;
+ ret = AImage_getFormat(img, &format);
+ if (ret != AMEDIA_OK || format == -1) {
+ ALOGE("%s: get format for image %p failed! ret: %d, format %d",
+ __FUNCTION__, img, ret, format);
+ return ret;
}
- void *bufferPointer = nullptr;
- android_ycbcr ycbcr = android_ycbcr();
-
- if (mSlots[slot].mGraphicBuffer->getPixelFormat() ==
- HAL_PIXEL_FORMAT_YCbCr_420_888) {
- err = mSlots[slot].mGraphicBuffer->lockYCbCr(
- GraphicBuffer::USAGE_SW_READ_OFTEN,
- b.mCrop,
- &ycbcr);
-
- if (err != OK) {
- ALOGE("Unable to lock YCbCr buffer for CPU reading: %s (%d)",
- strerror(-err), err);
- return err;
- }
- bufferPointer = ycbcr.y;
- } else {
- err = mSlots[slot].mGraphicBuffer->lock(
- GraphicBuffer::USAGE_SW_READ_OFTEN,
- b.mCrop,
- &bufferPointer);
-
- if (err != OK) {
- ALOGE("Unable to lock buffer for CPU reading: %s (%d)",
- strerror(-err), err);
- return err;
- }
+ if (format != AIMAGE_FORMAT_YUV_420_888 && format != AIMAGE_FORMAT_RGBA_8888) {
+ ALOGE("Format %d not supported", format);
+ return AMEDIA_ERROR_INVALID_OBJECT;
}
- size_t lockedIdx = 0;
- rsAssert(mAcquiredBuffer[idx].mSlot == BufferQueue::INVALID_BUFFER_SLOT);
+ uint8_t *data = nullptr;
+ int dataLength = 0;
+ ret = AImage_getPlaneData(img, 0, &data, &dataLength);
+ if (ret != AMEDIA_OK || data == nullptr || dataLength <= 0) {
+ ALOGE("%s: get data for image %p failed! ret: %d, data %p, len %d",
+ __FUNCTION__, img, ret, data, dataLength);
+ return ret;
+ }
- mAcquiredBuffer[idx].mSlot = slot;
- mAcquiredBuffer[idx].mBufferPointer = bufferPointer;
- mAcquiredBuffer[idx].mGraphicBuffer = mSlots[slot].mGraphicBuffer;
+ int64_t timestamp = -1;
+ ret = AImage_getTimestamp(img, ×tamp);
+ if (ret != AMEDIA_OK || timestamp == -1) {
+ ALOGE("%s: get timestamp for image %p failed! ret: %d",
+ __FUNCTION__, img, ret);
+ return ret;
+ }
- mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = reinterpret_cast<uint8_t*>(bufferPointer);
- mAlloc[idx]->mHal.drvState.lod[0].stride = mSlots[slot].mGraphicBuffer->getStride() *
- mAlloc[idx]->mHal.state.type->getElementSizeBytes();
- mAlloc[idx]->mHal.state.nativeBuffer = mAcquiredBuffer[idx].mGraphicBuffer->getNativeBuffer();
- mAlloc[idx]->mHal.state.timestamp = b.mTimestamp;
+ int32_t rowstride = -1;
+ ret = AImage_getPlaneRowStride(img, 0, &rowstride);
+ if (ret != AMEDIA_OK || rowstride == -1) {
+ ALOGE("%s: get row stride for image %p failed! ret: %d, rowstride %d",
+ __FUNCTION__, img, ret, rowstride);
+ return ret;
+ }
- rsAssert(mAlloc[idx]->mHal.drvState.lod[0].dimX ==
- mSlots[slot].mGraphicBuffer->getWidth());
- rsAssert(mAlloc[idx]->mHal.drvState.lod[0].dimY ==
- mSlots[slot].mGraphicBuffer->getHeight());
+ mAcquiredBuffer[idx].mBufferPointer = data;
- //mAlloc->format = mSlots[buf].mGraphicBuffer->getPixelFormat();
+ mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = data;
+ mAlloc[idx]->mHal.drvState.lod[0].stride = rowstride;
+ mAlloc[idx]->mHal.state.timestamp = timestamp;
- //mAlloc->crop = b.mCrop;
- //mAlloc->transform = b.mTransform;
- //mAlloc->scalingMode = b.mScalingMode;
- //mAlloc->frameNumber = b.mFrameNumber;
-
- // For YUV Allocations, we need to populate the drvState with details of how
- // the data is layed out.
- // RenderScript requests a buffer in the YCbCr_420_888 format.
- // The Camera HAL can return a buffer of YCbCr_420_888 or YV12, regardless
- // of the requested format.
- // mHal.state.yuv contains the requested format,
- // mGraphicBuffer->getPixelFormat() is the returned format.
- if (mAlloc[idx]->mHal.state.yuv == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+ if (format == AIMAGE_FORMAT_YUV_420_888) {
const int yWidth = mAlloc[idx]->mHal.drvState.lod[0].dimX;
const int yHeight = mAlloc[idx]->mHal.drvState.lod[0].dimY;
- if (mSlots[slot].mGraphicBuffer->getPixelFormat() ==
- HAL_PIXEL_FORMAT_YCbCr_420_888) {
- const int cWidth = yWidth / 2;
- const int cHeight = yHeight / 2;
+ const int cWidth = yWidth / 2;
+ const int cHeight = yHeight / 2;
- mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
- mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
- mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
- mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
-
- mAlloc[idx]->mHal.drvState.lod[0].mallocPtr = ycbcr.y;
- mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = ycbcr.cb;
- mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = ycbcr.cr;
-
- 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[idx]->mHal.drvState.yuv.shift = 1;
- mAlloc[idx]->mHal.drvState.yuv.step = ycbcr.chroma_step;
- mAlloc[idx]->mHal.drvState.lodCount = 3;
- } else if (mSlots[slot].mGraphicBuffer->getPixelFormat() ==
- HAL_PIXEL_FORMAT_YV12) {
- // For YV12, the data layout is Y, followed by Cr, followed by Cb;
- // for YCbCr_420_888, it's Y, followed by Cb, followed by Cr.
- // RenderScript assumes lod[0] is Y, lod[1] is Cb, and lod[2] is Cr.
- const int cWidth = yWidth / 2;
- const int cHeight = yHeight / 2;
-
- mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
- mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
- mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
- mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
-
- size_t yStride = rsRound(yWidth *
- mAlloc[idx]->mHal.state.type->getElementSizeBytes(), 16);
- size_t cStride = rsRound(yStride >> 1, 16);
-
- uint8_t *yPtr = (uint8_t *)mAlloc[idx]->mHal.drvState.lod[0].mallocPtr;
- uint8_t *crPtr = yPtr + yStride * yHeight;
- uint8_t *cbPtr = crPtr + cStride * cHeight;
-
- mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = cbPtr;
- mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = crPtr;
-
- mAlloc[idx]->mHal.drvState.lod[0].stride = yStride;
- mAlloc[idx]->mHal.drvState.lod[1].stride = cStride;
- mAlloc[idx]->mHal.drvState.lod[2].stride = cStride;
-
- mAlloc[idx]->mHal.drvState.yuv.shift = 1;
- mAlloc[idx]->mHal.drvState.yuv.step = 1;
- mAlloc[idx]->mHal.drvState.lodCount = 3;
- } else {
- ALOGD("Unrecognized format: %d",
- mSlots[slot].mGraphicBuffer->getPixelFormat());
+ uint8_t *uData = nullptr;
+ int uDataLength = 0;
+ ret = AImage_getPlaneData(img, 1, &uData, &uDataLength);
+ if (ret != AMEDIA_OK || uData == nullptr || uDataLength <= 0) {
+ ALOGE("%s: get U data for image %p failed! ret: %d, data %p, len %d",
+ __FUNCTION__, img, ret, uData, uDataLength);
+ return ret;
}
+
+ uint8_t *vData = nullptr;
+ int vDataLength = 0;
+ ret = AImage_getPlaneData(img, 2, &vData, &vDataLength);
+ if (ret != AMEDIA_OK || vData == nullptr || vDataLength <= 0) {
+ ALOGE("%s: get V data for image %p failed! ret: %d, data %p, len %d",
+ __FUNCTION__, img, ret, vData, vDataLength);
+ return ret;
+ }
+
+ int32_t uRowStride = -1;
+ ret = AImage_getPlaneRowStride(img, 1, &uRowStride);
+ if (ret != AMEDIA_OK || uRowStride == -1) {
+ ALOGE("%s: get U row stride for image %p failed! ret: %d, uRowStride %d",
+ __FUNCTION__, img, ret, uRowStride);
+ return ret;
+ }
+
+ int32_t vRowStride = -1;
+ ret = AImage_getPlaneRowStride(img, 2, &vRowStride);
+ if (ret != AMEDIA_OK || vRowStride == -1) {
+ ALOGE("%s: get V row stride for image %p failed! ret: %d, vRowStride %d",
+ __FUNCTION__, img, ret, vRowStride);
+ return ret;
+ }
+
+ int32_t uPixStride = -1;
+ ret = AImage_getPlanePixelStride(img, 1, &uPixStride);
+ if (ret != AMEDIA_OK || uPixStride == -1) {
+ ALOGE("%s: get U pixel stride for image %p failed! ret: %d, uPixStride %d",
+ __FUNCTION__, img, ret, uPixStride);
+ return ret;
+ }
+
+ mAlloc[idx]->mHal.drvState.lod[1].dimX = cWidth;
+ mAlloc[idx]->mHal.drvState.lod[1].dimY = cHeight;
+ mAlloc[idx]->mHal.drvState.lod[2].dimX = cWidth;
+ mAlloc[idx]->mHal.drvState.lod[2].dimY = cHeight;
+
+ mAlloc[idx]->mHal.drvState.lod[1].mallocPtr = uData;
+ mAlloc[idx]->mHal.drvState.lod[2].mallocPtr = vData;
+
+ mAlloc[idx]->mHal.drvState.lod[1].stride = uRowStride;
+ mAlloc[idx]->mHal.drvState.lod[2].stride = vRowStride;
+
+ mAlloc[idx]->mHal.drvState.yuv.shift = 1;
+ mAlloc[idx]->mHal.drvState.yuv.step = uPixStride;
+ mAlloc[idx]->mHal.drvState.lodCount = 3;
}
- return OK;
+ return AMEDIA_OK;
}
-status_t GrallocConsumer::unlockBuffer(uint32_t idx) {
- Mutex::Autolock _l(mMutex);
- return releaseAcquiredBufferLocked(idx);
-}
-
-status_t GrallocConsumer::releaseAcquiredBufferLocked(uint32_t idx) {
- status_t err;
+media_status_t GrallocConsumer::unlockBuffer(uint32_t idx) {
+ media_status_t ret;
if (idx >= mNumAlloc) {
ALOGE("Invalid buffer index: %d", idx);
- return BAD_VALUE;
+ return AMEDIA_ERROR_INVALID_PARAMETER;
}
- if (mAcquiredBuffer[idx].mGraphicBuffer == nullptr) {
- return OK;
+ if (mAcquiredBuffer[idx].mImg == nullptr) {
+ return AMEDIA_OK;
}
- err = mAcquiredBuffer[idx].mGraphicBuffer->unlock();
- if (err != OK) {
- ALOGE("%s: Unable to unlock graphic buffer", __FUNCTION__);
- return err;
- }
- 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 (mAcquiredBuffer[idx].mGraphicBuffer == mSlots[buf].mGraphicBuffer) {
- releaseBufferLocked(
- buf, mAcquiredBuffer[idx].mGraphicBuffer,
- EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
- }
-
- mAcquiredBuffer[idx].mSlot = BufferQueue::INVALID_BUFFER_SLOT;
- mAcquiredBuffer[idx].mBufferPointer = nullptr;
- mAcquiredBuffer[idx].mGraphicBuffer.clear();
- return OK;
+ AImage_delete(mAcquiredBuffer[idx].mImg);
+ mAcquiredBuffer[idx].mImg = nullptr;
+ return AMEDIA_OK;
}
uint32_t GrallocConsumer::getNextAvailableIdx(Allocation *a) {
@@ -291,9 +255,9 @@
ALOGV("Buffer index already released: %d", idx);
return true;
}
- status_t err;
- err = unlockBuffer(idx);
- if (err != OK) {
+ media_status_t ret;
+ ret = unlockBuffer(idx);
+ if (ret != OK) {
ALOGE("Unable to unlock graphic buffer");
return false;
}
@@ -302,5 +266,14 @@
return true;
}
+bool GrallocConsumer::isActive() {
+ for (uint32_t i = 0; i < mNumAlloc; i++) {
+ if (isIdxUsed[i]) {
+ return true;
+ }
+ }
+ return false;
+}
+
} // namespace renderscript
} // namespace android
diff --git a/rsGrallocConsumer.h b/rsGrallocConsumer.h
index 2c64551..d279145 100644
--- a/rsGrallocConsumer.h
+++ b/rsGrallocConsumer.h
@@ -17,20 +17,15 @@
#ifndef ANDROID_RS_GRALLOC_CONSUMER_H
#define ANDROID_RS_GRALLOC_CONSUMER_H
-#include <gui/ConsumerBase.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include <utils/String8.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-
+#include "NdkImage.h"
+#include "NdkImageReader.h"
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
class Allocation;
+class Context;
/**
* CpuConsumer is a BufferQueue consumer endpoint that allows direct CPU
@@ -39,38 +34,39 @@
* CpuConsumer owner. Sets gralloc usage flags to be software-read-only.
* This queue is synchronous by default.
*/
-class GrallocConsumer : public ConsumerBase
+class GrallocConsumer
{
public:
- typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
-
- GrallocConsumer(Allocation *, const sp<IGraphicBufferConsumer>& bq, int flags, uint32_t numAlloc);
+ GrallocConsumer(const Context *, Allocation *, uint32_t numAlloc);
virtual ~GrallocConsumer();
- status_t lockNextBuffer(uint32_t idx = 0);
- status_t unlockBuffer(uint32_t idx = 0);
+ ANativeWindow* getNativeWindow();
+ media_status_t lockNextBuffer(uint32_t idx = 0);
+ media_status_t unlockBuffer(uint32_t idx = 0);
uint32_t getNextAvailableIdx(Allocation *a);
bool releaseIdx(uint32_t idx);
+ bool isActive();
uint32_t mNumAlloc;
+ static void onFrameAvailable(void* obj, AImageReader* reader);
private:
- status_t releaseAcquiredBufferLocked(uint32_t idx);
+ media_status_t releaseAcquiredBufferLocked(uint32_t idx);
// Boolean array to check if a position has been occupied or not.
bool *isIdxUsed;
Allocation **mAlloc;
+ const Context *mCtx;
+ AImageReader* mImgReader;
+ ANativeWindow* mNativeWindow;
+ AImageReader_ImageListener mReaderCb;
// Tracking for buffers acquired by the user
struct AcquiredBuffer {
- // Need to track the original mSlot index and the buffer itself because
- // the mSlot entry may be freed/reused before the acquired buffer is
- // released.
- int mSlot;
- sp<GraphicBuffer> mGraphicBuffer;
- void *mBufferPointer;
+ AImage *mImg;
+ uint8_t *mBufferPointer;
AcquiredBuffer() :
- mSlot(BufferQueue::INVALID_BUFFER_SLOT),
+ mImg(nullptr),
mBufferPointer(nullptr) {
}
};
diff --git a/rs_hal.h b/rs_hal.h
index 4534126..5d87a50 100644
--- a/rs_hal.h
+++ b/rs_hal.h
@@ -36,7 +36,7 @@
* !! Be very careful when merging or cherry picking between branches!
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
*/
-#define RS_HAL_VERSION 100
+#define RS_HAL_VERSION 200
/**
* The interface for loading RenderScript drivers
diff --git a/rsov/driver/Android.mk b/rsov/driver/Android.mk
index 8f4a14f..3183195 100644
--- a/rsov/driver/Android.mk
+++ b/rsov/driver/Android.mk
@@ -43,7 +43,7 @@
frameworks/compile/libbcc/include \
frameworks/native/vulkan/include \
frameworks/rs \
- frameworks/rs/cpu_ref \
+ frameworks/rs/cpu_ref
LOCAL_C_INCLUDES += \