Add BufferItemConsumer, a simple BufferQueue consumer.
BufferItemConsumer allows for acquiring BufferQueue's BufferItems, which contain all the data and metadata the BufferQueue has for a given graphics buffer. This consumer is useful when direct access to the native buffer_handles is needed by the client. Also includes a minor cleanup of CpuConsumer's use of 'virtual'. Bug: 6243944 Change-Id: If7dc4192b15ac499555f1eda42a85140f2434795
This commit is contained in:
parent
f57e7540d4
commit
e232fdca2a
91
include/gui/BufferItemConsumer.h
Normal file
91
include/gui/BufferItemConsumer.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H
|
||||
#define ANDROID_GUI_BUFFERITEMCONSUMER_H
|
||||
|
||||
#include <gui/ConsumerBase.h>
|
||||
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
#include <utils/String8.h>
|
||||
#include <utils/Vector.h>
|
||||
#include <utils/threads.h>
|
||||
|
||||
#define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID "mBufferItemConsumer"
|
||||
|
||||
namespace android {
|
||||
|
||||
/**
|
||||
* BufferItemConsumer is a BufferQueue consumer endpoint that allows clients
|
||||
* access to the whole BufferItem entry from BufferQueue. Multiple buffers may
|
||||
* be acquired at once, to be used concurrently by the client. This consumer can
|
||||
* operate either in synchronous or asynchronous mode.
|
||||
*/
|
||||
class BufferItemConsumer: public ConsumerBase
|
||||
{
|
||||
public:
|
||||
typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;
|
||||
|
||||
typedef BufferQueue::BufferItem BufferItem;
|
||||
|
||||
enum { INVALID_BUFFER_SLOT = BufferQueue::INVALID_BUFFER_SLOT };
|
||||
enum { NO_BUFFER_AVAILABLE = BufferQueue::NO_BUFFER_AVAILABLE };
|
||||
|
||||
// Create a new buffer item consumer. The consumerUsage parameter determines
|
||||
// the consumer usage flags passed to the graphics allocator. The
|
||||
// bufferCount parameter specifies how many buffers can be locked for user
|
||||
// access at the same time.
|
||||
BufferItemConsumer(uint32_t consumerUsage,
|
||||
int bufferCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS,
|
||||
bool synchronousMode = false);
|
||||
|
||||
virtual ~BufferItemConsumer();
|
||||
|
||||
// set the name of the BufferItemConsumer that will be used to identify it in
|
||||
// log messages.
|
||||
void setName(const String8& name);
|
||||
|
||||
// Gets the next graphics buffer from the producer, filling out the
|
||||
// passed-in BufferItem structure. Returns NO_BUFFER_AVAILABLE if the queue
|
||||
// of buffers is empty, and INVALID_OPERATION if the maximum number of
|
||||
// buffers is already acquired.
|
||||
//
|
||||
// Only a fixed number of buffers can be acquired at a time, determined by
|
||||
// the construction-time bufferCount parameter. If INVALID_OPERATION is
|
||||
// returned by acquireBuffer, then old buffers must be returned to the
|
||||
// queue by calling releaseBuffer before more buffers can be acquired.
|
||||
//
|
||||
// If waitForFence is true, and the acquired BufferItem has a valid fence object,
|
||||
// acquireBuffer will wait on the fence with no timeout before returning.
|
||||
status_t acquireBuffer(BufferItem *item, bool waitForFence = true);
|
||||
|
||||
// Returns an acquired buffer to the queue, allowing it to be reused. Since
|
||||
// only a fixed number of buffers may be acquired at a time, old buffers
|
||||
// must be released by calling releaseBuffer to ensure new buffers can be
|
||||
// acquired by acquireBuffer. Once a BufferItem is released, the caller must
|
||||
// not access any members of the BufferItem, and should immediately remove
|
||||
// all of its references to the BufferItem itself.
|
||||
status_t releaseBuffer(const BufferItem &item,
|
||||
const sp<Fence>& releaseFence = Fence::NO_FENCE);
|
||||
|
||||
sp<ISurfaceTexture> getProducerInterface() const { return getBufferQueue(); }
|
||||
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_GUI_CPUCONSUMER_H
|
@ -59,6 +59,8 @@ class CpuConsumer: public ConsumerBase
|
||||
// how many buffers can be locked for user access at the same time.
|
||||
CpuConsumer(uint32_t maxLockedBuffers);
|
||||
|
||||
virtual ~CpuConsumer();
|
||||
|
||||
// set the name of the CpuConsumer that will be used to identify it in
|
||||
// log messages.
|
||||
void setName(const String8& name);
|
||||
@ -86,7 +88,7 @@ class CpuConsumer: public ConsumerBase
|
||||
// Maximum number of buffers that can be locked at a time
|
||||
uint32_t mMaxLockedBuffers;
|
||||
|
||||
void freeBufferLocked(int slotIndex);
|
||||
virtual void freeBufferLocked(int slotIndex);
|
||||
|
||||
// Array for tracking pointers passed to the consumer, matching the
|
||||
// mSlots indexing
|
||||
|
@ -23,7 +23,8 @@ LOCAL_SRC_FILES:= \
|
||||
Surface.cpp \
|
||||
SurfaceComposerClient.cpp \
|
||||
DummyConsumer.cpp \
|
||||
CpuConsumer.cpp
|
||||
CpuConsumer.cpp \
|
||||
BufferItemConsumer.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libbinder \
|
||||
|
93
libs/gui/BufferItemConsumer.cpp
Normal file
93
libs/gui/BufferItemConsumer.cpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2012 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//#define LOG_NDEBUG 0
|
||||
#define LOG_TAG "BufferItemConsumer"
|
||||
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <gui/BufferItemConsumer.h>
|
||||
|
||||
#define BI_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
|
||||
#define BI_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
|
||||
#define BI_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
|
||||
#define BI_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
|
||||
#define BI_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
|
||||
|
||||
namespace android {
|
||||
|
||||
BufferItemConsumer::BufferItemConsumer(uint32_t consumerUsage,
|
||||
int bufferCount, bool synchronousMode) :
|
||||
ConsumerBase(new BufferQueue(true, bufferCount) )
|
||||
{
|
||||
mBufferQueue->setConsumerUsageBits(consumerUsage);
|
||||
mBufferQueue->setSynchronousMode(synchronousMode);
|
||||
}
|
||||
|
||||
BufferItemConsumer::~BufferItemConsumer() {
|
||||
}
|
||||
|
||||
void BufferItemConsumer::setName(const String8& name) {
|
||||
Mutex::Autolock _l(mMutex);
|
||||
mName = name;
|
||||
mBufferQueue->setConsumerName(name);
|
||||
}
|
||||
|
||||
status_t BufferItemConsumer::acquireBuffer(BufferItem *item, bool waitForFence) {
|
||||
status_t err;
|
||||
|
||||
if (!item) return BAD_VALUE;
|
||||
|
||||
Mutex::Autolock _l(mMutex);
|
||||
|
||||
err = acquireBufferLocked(item);
|
||||
if (err != OK) {
|
||||
if (err != NO_BUFFER_AVAILABLE) {
|
||||
BI_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
if (waitForFence && item->mFence.get()) {
|
||||
err = item->mFence->wait(Fence::TIMEOUT_NEVER);
|
||||
if (err != OK) {
|
||||
BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
|
||||
strerror(-err), err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
item->mGraphicBuffer = mSlots[item->mBuf].mGraphicBuffer;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t BufferItemConsumer::releaseBuffer(const BufferItem &item,
|
||||
const sp<Fence>& releaseFence) {
|
||||
status_t err;
|
||||
|
||||
Mutex::Autolock _l(mMutex);
|
||||
|
||||
err = releaseBufferLocked(item.mBuf, EGL_NO_DISPLAY,
|
||||
EGL_NO_SYNC_KHR, releaseFence);
|
||||
if (err != OK) {
|
||||
BI_LOGE("Failed to release buffer: %s (%d)",
|
||||
strerror(-err), err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
} // namespace android
|
@ -43,6 +43,9 @@ CpuConsumer::CpuConsumer(uint32_t maxLockedBuffers) :
|
||||
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
|
||||
}
|
||||
|
||||
CpuConsumer::~CpuConsumer() {
|
||||
}
|
||||
|
||||
void CpuConsumer::setName(const String8& name) {
|
||||
Mutex::Autolock _l(mMutex);
|
||||
mName = name;
|
||||
|
Loading…
Reference in New Issue
Block a user