From 31152b94cd0471a3853fb658e9aff507d4eec384 Mon Sep 17 00:00:00 2001 From: Ramkumar Radhakrishnan Date: Wed, 7 Nov 2012 11:30:19 -0800 Subject: Add support for custom buffer sizes. Add native window properties NATIVE_WINDOW_SET_BUFFERS_SIZE to the perform function of SurfaceTextureClient to set the user defined size of graphic buffers. Change-Id: I1dc2203990a3641fbb9ddab9a86f7e9017f05270 --- include/gui/BufferQueue.h | 10 ++++++ include/gui/IGraphicBufferAlloc.h | 3 ++ include/gui/ISurfaceTexture.h | 10 ++++++ include/gui/SurfaceTextureClient.h | 13 +++++++- include/ui/GraphicBuffer.h | 13 ++++++-- include/ui/GraphicBufferAllocator.h | 5 +++ libs/gui/BufferQueue.cpp | 9 +++++ libs/gui/IGraphicBufferAlloc.cpp | 21 ++++++++++++ libs/gui/ISurfaceTexture.cpp | 26 +++++++++++++++ libs/gui/SurfaceTextureClient.cpp | 38 ++++++++++++++++++++++ libs/ui/GraphicBuffer.cpp | 33 +++++++++++++++++++ libs/ui/GraphicBufferAllocator.cpp | 24 +++++++++++++- .../DisplayHardware/GraphicBufferAlloc.cpp | 15 +++++++++ .../DisplayHardware/GraphicBufferAlloc.h | 5 +++ 14 files changed, 221 insertions(+), 4 deletions(-) diff --git a/include/gui/BufferQueue.h b/include/gui/BufferQueue.h index 9e265ba..02598b0 100644 --- a/include/gui/BufferQueue.h +++ b/include/gui/BufferQueue.h @@ -148,6 +148,16 @@ public: // The default mode is asynchronous. virtual status_t setSynchronousMode(bool enabled); +#ifdef QCOM_BSP + // setBufferSize enables us to specify user defined sizes for the buffers + // that need to be allocated by surfaceflinger for its client. This is + // useful for cases where the client doesn't want the gralloc to calculate + // buffer size. client should reset this value to 0, if it wants gralloc + // to calculate the size for the buffer. this will take effect from next + // dequeue buffer. + virtual status_t setBuffersSize(int size); +#endif + // connect attempts to connect a producer client API to the BufferQueue. // This must be called before any other ISurfaceTexture methods are called // except for getAllocator. diff --git a/include/gui/IGraphicBufferAlloc.h b/include/gui/IGraphicBufferAlloc.h index cee41d9..adc0b7f 100644 --- a/include/gui/IGraphicBufferAlloc.h +++ b/include/gui/IGraphicBufferAlloc.h @@ -38,6 +38,9 @@ public: */ virtual sp createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, status_t* error) = 0; +#ifdef QCOM_BSP + virtual void setGraphicBufferSize(int size) = 0; +#endif }; // ---------------------------------------------------------------------------- diff --git a/include/gui/ISurfaceTexture.h b/include/gui/ISurfaceTexture.h index ae7c5c2..f0beab6 100644 --- a/include/gui/ISurfaceTexture.h +++ b/include/gui/ISurfaceTexture.h @@ -164,6 +164,16 @@ public: // The default mode is asynchronous. virtual status_t setSynchronousMode(bool enabled) = 0; +#ifdef QCOM_BSP + // setBufferSize enables to specify the user defined size of the buffer + // that needs to be allocated by surfaceflinger for its client. This is + // useful for cases where the client doesn't want the gralloc to calculate + // buffer size. client should reset this value to 0, if it wants gralloc to + // calculate the size for the buffer. this will take effect from next + // dequeue buffer. + virtual status_t setBuffersSize(int size) = 0; +#endif + // connect attempts to connect a client API to the SurfaceTexture. This // must be called before any other ISurfaceTexture methods are called except // for getAllocator. diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h index 50fd1ba..108126d 100644 --- a/include/gui/SurfaceTextureClient.h +++ b/include/gui/SurfaceTextureClient.h @@ -93,6 +93,9 @@ private: int dispatchSetCrop(va_list args); int dispatchSetPostTransformCrop(va_list args); int dispatchSetUsage(va_list args); +#ifdef QCOM_BSP + int dispatchSetBuffersSize(va_list args); +#endif int dispatchLock(va_list args); int dispatchUnlockAndPost(va_list args); @@ -103,7 +106,9 @@ protected: virtual int perform(int operation, va_list args); virtual int query(int what, int* value) const; virtual int setSwapInterval(int interval); - +#ifdef QCOM_BSP + virtual int setBuffersSize(int size); +#endif virtual int lockBuffer_DEPRECATED(ANativeWindowBuffer* buffer); virtual int connect(int api); @@ -161,6 +166,12 @@ private: // at the next deuque operation. It is initialized to 0. uint32_t mReqUsage; +#ifdef QCOM_BSP + // mReqSize is the size of the buffer that will be requested + // at the next dequeue operation. It is initialized to 0. + uint32_t mReqSize; +#endif + // mTimestamp is the timestamp that will be used for the next buffer queue // operation. It defaults to NATIVE_WINDOW_TIMESTAMP_AUTO, which means that // a timestamp is auto-generated when queueBuffer is called. diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h index 1c84d0e..60bbf18 100644 --- a/include/ui/GraphicBuffer.h +++ b/include/ui/GraphicBuffer.h @@ -72,6 +72,12 @@ public: GraphicBuffer(); +#ifdef QCOM_BSP + // creates buffer of bufferSize + GraphicBuffer(uint32_t w, uint32_t h, + PixelFormat format, uint32_t usage, uint32_t bufferSize); +#endif + // creates w * h buffer GraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage); @@ -133,9 +139,12 @@ private: GraphicBuffer& operator = (const GraphicBuffer& rhs); const GraphicBuffer& operator = (const GraphicBuffer& rhs) const; - status_t initSize(uint32_t w, uint32_t h, PixelFormat format, + status_t initSize(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage); - +#ifdef QCOM_BSP + status_t initSize(uint32_t w, uint32_t h, PixelFormat format, + uint32_t usage, uint32_t bufferSize); +#endif void free_handle(); // Flattenable interface diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h index 6342aac..a4d5b8c 100644 --- a/include/ui/GraphicBufferAllocator.h +++ b/include/ui/GraphicBufferAllocator.h @@ -68,6 +68,11 @@ public: status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage, buffer_handle_t* handle, int32_t* stride); +#ifdef QCOM_BSP + status_t alloc(uint32_t w, uint32_t h, PixelFormat format, int usage, + buffer_handle_t* handle, int32_t* stride, uint32_t bufferSize); +#endif + status_t free(buffer_handle_t handle); void dump(String8& res) const; diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index 9f9b441..5226037 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -195,6 +195,15 @@ status_t BufferQueue::setBufferCount(int bufferCount) { return OK; } +#ifdef QCOM_BSP +status_t BufferQueue::setBuffersSize(int size) { + ST_LOGV("setBuffersSize: size=%d", size); + Mutex::Autolock lock(mMutex); + mGraphicBufferAlloc->setGraphicBufferSize(size); + return NO_ERROR; +} +#endif + int BufferQueue::query(int what, int* outValue) { ATRACE_CALL(); diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp index 139f219..8afb509 100644 --- a/libs/gui/IGraphicBufferAlloc.cpp +++ b/libs/gui/IGraphicBufferAlloc.cpp @@ -32,6 +32,9 @@ namespace android { enum { CREATE_GRAPHIC_BUFFER = IBinder::FIRST_CALL_TRANSACTION, +#ifdef QCOM_BSP + SET_GRAPHIC_BUFFER_SIZE, +#endif }; class BpGraphicBufferAlloc : public BpInterface @@ -63,6 +66,16 @@ public: *error = result; return graphicBuffer; } + +#ifdef QCOM_BSP + virtual void setGraphicBufferSize(int size) { + Parcel data, reply; + data.writeInterfaceToken( + IGraphicBufferAlloc::getInterfaceDescriptor()); + data.writeInt32(size); + remote()->transact(SET_GRAPHIC_BUFFER_SIZE, data, &reply); + } +#endif }; IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc"); @@ -108,6 +121,14 @@ status_t BnGraphicBufferAlloc::onTransact( } return NO_ERROR; } break; +#ifdef QCOM_BSP + case SET_GRAPHIC_BUFFER_SIZE: { + CHECK_INTERFACE(IGraphicBufferAlloc, data, reply); + int size = data.readInt32(); + setGraphicBufferSize(size); + return NO_ERROR; + } break; +#endif default: return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/ISurfaceTexture.cpp b/libs/gui/ISurfaceTexture.cpp index a0b1e74..4b20a36 100644 --- a/libs/gui/ISurfaceTexture.cpp +++ b/libs/gui/ISurfaceTexture.cpp @@ -38,6 +38,9 @@ enum { CANCEL_BUFFER, QUERY, SET_SYNCHRONOUS_MODE, +#ifdef QCOM_BSP + SET_BUFFERS_SIZE, +#endif CONNECT, DISCONNECT, }; @@ -156,6 +159,20 @@ public: return result; } +#ifdef QCOM_BSP + virtual status_t setBuffersSize(int size) { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); + data.writeInt32(size); + status_t result = remote()->transact(SET_BUFFERS_SIZE, data, &reply); + if (result != NO_ERROR) { + return result; + } + result = reply.readInt32(); + return result; + } +#endif + virtual status_t connect(int api, QueueBufferOutput* output) { Parcel data, reply; data.writeInterfaceToken(ISurfaceTexture::getInterfaceDescriptor()); @@ -266,6 +283,15 @@ status_t BnSurfaceTexture::onTransact( reply->writeInt32(res); return NO_ERROR; } break; +#ifdef QCOM_BSP + case SET_BUFFERS_SIZE: { + CHECK_INTERFACE(ISurfaceTexture, data, reply); + int size = data.readInt32(); + status_t res = setBuffersSize(size); + reply->writeInt32(res); + return NO_ERROR; + } break; +#endif case CONNECT: { CHECK_INTERFACE(ISurfaceTexture, data, reply); int api = data.readInt32(); diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp index afdbf04..e33b026 100644 --- a/libs/gui/SurfaceTextureClient.cpp +++ b/libs/gui/SurfaceTextureClient.cpp @@ -80,6 +80,9 @@ void SurfaceTextureClient::init() { mReqHeight = 0; mReqFormat = 0; mReqUsage = 0; +#ifdef QCOM_BSP + mReqSize = 0; +#endif mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; mCrop.clear(); mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; @@ -400,6 +403,11 @@ int SurfaceTextureClient::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_FORMAT: res = dispatchSetBuffersFormat(args); break; +#ifdef QCOM_BSP + case NATIVE_WINDOW_SET_BUFFERS_SIZE: + res = dispatchSetBuffersSize(args); + break; +#endif case NATIVE_WINDOW_LOCK: res = dispatchLock(args); break; @@ -451,6 +459,7 @@ int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) { int w = va_arg(args, int); int h = va_arg(args, int); int f = va_arg(args, int); + int err = setBuffersDimensions(w, h); if (err != 0) { return err; @@ -461,6 +470,7 @@ int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) { int SurfaceTextureClient::dispatchSetBuffersDimensions(va_list args) { int w = va_arg(args, int); int h = va_arg(args, int); + return setBuffersDimensions(w, h); } @@ -475,6 +485,13 @@ int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) { return setBuffersFormat(f); } +#ifdef QCOM_BSP +int SurfaceTextureClient::dispatchSetBuffersSize(va_list args) { + int size = va_arg(args, int); + return setBuffersSize(size); +} +#endif + int SurfaceTextureClient::dispatchSetScalingMode(va_list args) { int m = va_arg(args, int); return setScalingMode(m); @@ -530,6 +547,9 @@ int SurfaceTextureClient::disconnect(int api) { mReqWidth = 0; mReqHeight = 0; mReqUsage = 0; +#ifdef QCOM_BSP + mReqSize = 0; +#endif mCrop.clear(); mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; mTransform = 0; @@ -630,6 +650,24 @@ int SurfaceTextureClient::setBuffersFormat(int format) return NO_ERROR; } +#ifdef QCOM_BSP +int SurfaceTextureClient::setBuffersSize(int size) +{ + ATRACE_CALL(); + ALOGV("SurfaceTextureClient::setBuffersSize"); + + if (size<0) + return BAD_VALUE; + + Mutex::Autolock lock(mMutex); + if(mReqSize != (uint32_t)size) { + mReqSize = size; + return mSurfaceTexture->setBuffersSize(size); + } + return NO_ERROR; +} +#endif + int SurfaceTextureClient::setScalingMode(int mode) { ATRACE_CALL(); diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp index b9cab85..b447d00 100644 --- a/libs/ui/GraphicBuffer.cpp +++ b/libs/ui/GraphicBuffer.cpp @@ -60,6 +60,22 @@ GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, mInitCheck = initSize(w, h, reqFormat, reqUsage); } +#ifdef QCOM_BSP +GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, + PixelFormat reqFormat, uint32_t reqUsage, uint32_t bufferSize) + : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()), + mInitCheck(NO_ERROR), mIndex(-1) +{ + width = + height = + stride = + format = + usage = 0; + handle = NULL; + mInitCheck = initSize(w, h, reqFormat, reqUsage, bufferSize); +} +#endif + GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, PixelFormat inFormat, uint32_t inUsage, uint32_t inStride, native_handle_t* inHandle, bool keepOwnership) @@ -154,6 +170,23 @@ status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, return err; } +#ifdef QCOM_BSP +status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format, + uint32_t reqUsage, uint32_t bufferSize) +{ + GraphicBufferAllocator& allocator = GraphicBufferAllocator::get(); + status_t err = allocator.alloc(w, h, format, + reqUsage, &handle, &stride, bufferSize); + if (err == NO_ERROR) { + this->width = w; + this->height = h; + this->format = format; + this->usage = reqUsage; + } + return err; +} +#endif + status_t GraphicBuffer::lock(uint32_t usage, void** vaddr) { const Rect lockBounds(width, height); diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp index 2ea5696..9ad314a 100644 --- a/libs/ui/GraphicBufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -192,6 +192,17 @@ sp BufferLiberatorThread::sThread; status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format, int usage, buffer_handle_t* handle, int32_t* stride) { +#ifdef QCOM_BSP + status_t err = alloc(w, h, format, usage, handle, stride, 0); + return err; +} + +status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, + PixelFormat format, int usage, + buffer_handle_t* handle, + int32_t* stride, uint32_t bufferSize) +{ +#endif ATRACE_CALL(); // make sure to not allocate a N x 0 or 0 x N buffer, since this is // allowed from an API stand-point allocate a 1x1 buffer instead. @@ -216,7 +227,13 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma // by the android.opengl.cts.GLSurfaceViewTest CTS test. BufferLiberatorThread::maybeWaitForLiberation(); - err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride); +#ifdef QCOM_BSP + if (bufferSize) + err = mAllocDev->allocSize(mAllocDev, w, h, + format, usage, handle, stride, bufferSize); + else +#endif + err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride); if (err != NO_ERROR) { ALOGW("WOW! gralloc alloc failed, waiting for pending frees!"); @@ -224,8 +241,13 @@ status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat forma err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride); } +#ifdef QCOM_BSP + ALOGW_IF(err, "alloc(%u, %u, %d, %08x, %d ...) failed %d (%s)", + w, h, format, usage, bufferSize, err, strerror(-err)); +#else ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)", w, h, format, usage, err, strerror(-err)); +#endif if (err == NO_ERROR) { Mutex::Autolock _l(sLock); diff --git a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp index 965ff01..0c94c7d 100644 --- a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp +++ b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.cpp @@ -26,6 +26,9 @@ namespace android { // ---------------------------------------------------------------------------- GraphicBufferAlloc::GraphicBufferAlloc() { +#ifdef QCOM_BSP + mBufferSize = 0; +#endif } GraphicBufferAlloc::~GraphicBufferAlloc() { @@ -33,7 +36,13 @@ GraphicBufferAlloc::~GraphicBufferAlloc() { sp GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, status_t* error) { +#ifdef QCOM_BSP + sp graphicBuffer(new GraphicBuffer(w, h, format, + usage, mBufferSize)); +#else sp graphicBuffer(new GraphicBuffer(w, h, format, usage)); +#endif + status_t err = graphicBuffer->initCheck(); *error = err; if (err != 0 || graphicBuffer->handle == 0) { @@ -48,6 +57,12 @@ sp GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h return graphicBuffer; } +#ifdef QCOM_BSP +void GraphicBufferAlloc::setGraphicBufferSize(int size) { + mBufferSize = size; +} +#endif + // ---------------------------------------------------------------------------- }; // namespace android // ---------------------------------------------------------------------------- diff --git a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h index b08750c..521383d 100644 --- a/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h +++ b/services/surfaceflinger/DisplayHardware/GraphicBufferAlloc.h @@ -35,6 +35,11 @@ public: virtual ~GraphicBufferAlloc(); virtual sp createGraphicBuffer(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage, status_t* error); +#ifdef QCOM_BSP + virtual void setGraphicBufferSize(int size); +private: + int mBufferSize; +#endif }; -- cgit v1.1