summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2014-06-30 17:38:44 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-06-27 15:56:14 +0000
commitdc56bf721a9f29621fd57e1d861142fa9b2d3663 (patch)
tree798493ee885dbc05107019a2c5b2bb97616f07c4 /libs
parentff0d588db52e29cf679d10c53affea9b8d867f26 (diff)
parent29a3e90879fd96404c971e7187cd0e05927bbce0 (diff)
downloadframeworks_native-dc56bf721a9f29621fd57e1d861142fa9b2d3663.zip
frameworks_native-dc56bf721a9f29621fd57e1d861142fa9b2d3663.tar.gz
frameworks_native-dc56bf721a9f29621fd57e1d861142fa9b2d3663.tar.bz2
Merge "BufferQueue: Add allocateBuffers method"
Diffstat (limited to 'libs')
-rw-r--r--libs/gui/BufferQueueProducer.cpp55
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp25
-rw-r--r--libs/gui/Surface.cpp7
3 files changed, 87 insertions, 0 deletions
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 7017ddf..70c3ff3 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -331,6 +331,7 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
status_t error;
+ BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
width, height, format, usage, &error));
if (graphicBuffer == NULL) {
@@ -852,6 +853,60 @@ status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream)
return NO_ERROR;
}
+void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
+ uint32_t height, uint32_t format, uint32_t usage) {
+ Vector<int> freeSlots;
+
+ Mutex::Autolock lock(mCore->mMutex);
+
+ int currentBufferCount = 0;
+ for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
+ if (mSlots[slot].mGraphicBuffer != NULL) {
+ ++currentBufferCount;
+ } else {
+ if (mSlots[slot].mBufferState != BufferSlot::FREE) {
+ BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE",
+ slot);
+ continue;
+ }
+
+ freeSlots.push_front(slot);
+ }
+ }
+
+ int maxBufferCount = mCore->getMaxBufferCountLocked(async);
+ BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers",
+ currentBufferCount, maxBufferCount);
+ for (; currentBufferCount < maxBufferCount; ++currentBufferCount) {
+ if (freeSlots.empty()) {
+ BQ_LOGE("allocateBuffers: ran out of free slots");
+ return;
+ }
+
+ width = width > 0 ? width : mCore->mDefaultWidth;
+ height = height > 0 ? height : mCore->mDefaultHeight;
+ format = format != 0 ? format : mCore->mDefaultBufferFormat;
+ usage |= mCore->mConsumerUsageBits;
+
+ status_t result = NO_ERROR;
+ sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
+ width, height, format, usage, &result));
+ if (result != NO_ERROR) {
+ BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format"
+ " %u, usage %u)", width, height, format, usage);
+ return;
+ }
+
+ int slot = freeSlots[freeSlots.size() - 1];
+ mCore->freeBufferLocked(slot); // Clean up the slot first
+ mSlots[slot].mGraphicBuffer = graphicBuffer;
+ mSlots[slot].mFrameNumber = 0;
+ mSlots[slot].mFence = Fence::NO_FENCE;
+ BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot);
+ freeSlots.pop();
+ }
+}
+
void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
// If we're here, it means that a producer we were connected to died.
// We're guaranteed that we are still connected to it because we remove
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index aa6acb9..8d9a800 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -45,6 +45,7 @@ enum {
CONNECT,
DISCONNECT,
SET_SIDEBAND_STREAM,
+ ALLOCATE_BUFFERS,
};
class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -252,6 +253,21 @@ public:
}
return result;
}
+
+ virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
+ uint32_t format, uint32_t usage) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(async));
+ data.writeInt32(static_cast<int32_t>(width));
+ data.writeInt32(static_cast<int32_t>(height));
+ data.writeInt32(static_cast<int32_t>(format));
+ data.writeInt32(static_cast<int32_t>(usage));
+ status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("allocateBuffers failed to transact: %d", result);
+ }
+ }
};
IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
@@ -394,6 +410,15 @@ status_t BnGraphicBufferProducer::onTransact(
reply->writeInt32(result);
return NO_ERROR;
} break;
+ case ALLOCATE_BUFFERS:
+ CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+ bool async = static_cast<bool>(data.readInt32());
+ uint32_t width = static_cast<uint32_t>(data.readInt32());
+ uint32_t height = static_cast<uint32_t>(data.readInt32());
+ uint32_t format = static_cast<uint32_t>(data.readInt32());
+ uint32_t usage = static_cast<uint32_t>(data.readInt32());
+ allocateBuffers(async, width, height, format, usage);
+ return NO_ERROR;
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 88c45b2..8cb9189 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -91,6 +91,13 @@ void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
mGraphicBufferProducer->setSidebandStream(stream);
}
+void Surface::allocateBuffers() {
+ uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
+ uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
+ mGraphicBufferProducer->allocateBuffers(mSwapIntervalZero, mReqWidth,
+ mReqHeight, mReqFormat, mReqUsage);
+}
+
int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
Surface* c = getSelf(window);
return c->setSwapInterval(interval);