BufferQueue improvements and APIs changes
this is the first step of a series of improvements to BufferQueue. A few things happen in this change: - setSynchronousMode() goes away as well as the SynchronousModeAllowed flag - BufferQueue now defaults to (what used to be) synchronous mode - a new "controlled by app" flag is passed when creating consumers and producers those flags are used to put the BufferQueue in a mode where it will never block if both flags are set. This is achieved by: - returning an error from dequeueBuffer() if it would block - making sure a buffer is always available by replacing the previous buffer with the new one in queueBuffer() (note: this is similar to what asynchrnous mode used to be) Note: in this change EGL's swap-interval 0 is broken; this will be fixed in another change. Change-Id: I691f9507d6e2e158287e3039f2a79a4d4434211d
This commit is contained in:
parent
1962f65137
commit
595264f1af
@ -198,7 +198,7 @@ bool GLHelper::getShaderProgram(const char* name, GLuint* outPgm) {
|
||||
|
||||
bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h,
|
||||
sp<GLConsumer>* glConsumer, EGLSurface* surface) {
|
||||
sp<BufferQueue> bq = new BufferQueue(true, mGraphicBufferAlloc);
|
||||
sp<BufferQueue> bq = new BufferQueue(mGraphicBufferAlloc);
|
||||
sp<GLConsumer> glc = new GLConsumer(bq, name,
|
||||
GL_TEXTURE_EXTERNAL_OES, false);
|
||||
glc->setDefaultBufferSize(w, h);
|
||||
|
@ -51,9 +51,11 @@ class BufferItemConsumer: public ConsumerBase
|
||||
// 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.
|
||||
// controlledByApp tells whether this consumer is controlled by the
|
||||
// application.
|
||||
BufferItemConsumer(const sp<BufferQueue>& bq, uint32_t consumerUsage,
|
||||
int bufferCount = BufferQueue::MIN_UNDEQUEUED_BUFFERS,
|
||||
bool synchronousMode = false);
|
||||
bool controlledByApp = false);
|
||||
|
||||
virtual ~BufferItemConsumer();
|
||||
|
||||
|
@ -97,11 +97,9 @@ public:
|
||||
|
||||
|
||||
// BufferQueue manages a pool of gralloc memory slots to be used by
|
||||
// producers and consumers. allowSynchronousMode specifies whether or not
|
||||
// synchronous mode can be enabled by the producer. allocator is used to
|
||||
// allocate all the needed gralloc buffers.
|
||||
BufferQueue(bool allowSynchronousMode = true,
|
||||
const sp<IGraphicBufferAlloc>& allocator = NULL);
|
||||
// producers and consumers. allocator is used to allocate all the
|
||||
// needed gralloc buffers.
|
||||
BufferQueue(const sp<IGraphicBufferAlloc>& allocator = NULL);
|
||||
virtual ~BufferQueue();
|
||||
|
||||
// Query native window attributes. The "what" values are enumerated in
|
||||
@ -197,15 +195,6 @@ public:
|
||||
// will usually be the one obtained from dequeueBuffer.
|
||||
virtual void cancelBuffer(int buf, const sp<Fence>& fence);
|
||||
|
||||
// setSynchronousMode sets whether dequeueBuffer is synchronous or
|
||||
// asynchronous. In synchronous mode, dequeueBuffer blocks until
|
||||
// a buffer is available, the currently bound buffer can be dequeued and
|
||||
// queued buffers will be acquired in order. In asynchronous mode,
|
||||
// a queued buffer may be replaced by a subsequently queued buffer.
|
||||
//
|
||||
// The default mode is asynchronous.
|
||||
virtual status_t setSynchronousMode(bool enabled);
|
||||
|
||||
// connect attempts to connect a producer API to the BufferQueue. This
|
||||
// must be called before any other IGraphicBufferProducer methods are
|
||||
// called except for getAllocator. A consumer must already be connected.
|
||||
@ -215,7 +204,7 @@ public:
|
||||
// it's still connected to a producer).
|
||||
//
|
||||
// APIs are enumerated in window.h (e.g. NATIVE_WINDOW_API_CPU).
|
||||
virtual status_t connect(int api, QueueBufferOutput* output);
|
||||
virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output);
|
||||
|
||||
// disconnect attempts to disconnect a producer API from the BufferQueue.
|
||||
// Calling this method will cause any subsequent calls to other
|
||||
@ -312,9 +301,11 @@ public:
|
||||
// consumer may be connected, and when that consumer disconnects the
|
||||
// BufferQueue is placed into the "abandoned" state, causing most
|
||||
// interactions with the BufferQueue by the producer to fail.
|
||||
// controlledByApp indicates whether the consumer is controlled by
|
||||
// the application.
|
||||
//
|
||||
// consumer may not be NULL.
|
||||
status_t consumerConnect(const sp<ConsumerListener>& consumer);
|
||||
status_t consumerConnect(const sp<ConsumerListener>& consumer, bool controlledByApp);
|
||||
|
||||
// consumerDisconnect disconnects a consumer from the BufferQueue. All
|
||||
// buffers will be freed and the BufferQueue is placed in the "abandoned"
|
||||
@ -347,10 +338,6 @@ public:
|
||||
// fail if a producer is connected to the BufferQueue.
|
||||
status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);
|
||||
|
||||
// isSynchronousMode returns whether the BufferQueue is currently in
|
||||
// synchronous mode.
|
||||
bool isSynchronousMode() const;
|
||||
|
||||
// setConsumerName sets the name used in logging
|
||||
void setConsumerName(const String8& name);
|
||||
|
||||
@ -568,13 +555,18 @@ private:
|
||||
// to NULL and is written by consumerConnect and consumerDisconnect.
|
||||
sp<ConsumerListener> mConsumerListener;
|
||||
|
||||
// mConsumerControlledByApp whether the connected consumer is controlled by the
|
||||
// application.
|
||||
bool mConsumerControlledByApp;
|
||||
|
||||
// mDequeueBufferCannotBlock whether dequeueBuffer() isn't allowed to block.
|
||||
// this flag is set durring connect() when both consumer and producer are controlled
|
||||
// by the application.
|
||||
bool mDequeueBufferCannotBlock;
|
||||
|
||||
// mSynchronousMode whether we're in synchronous mode or not
|
||||
bool mSynchronousMode;
|
||||
|
||||
// mAllowSynchronousMode whether we allow synchronous mode or not. Set
|
||||
// when the BufferQueue is created (by the consumer).
|
||||
const bool mAllowSynchronousMode;
|
||||
|
||||
// mConnectedApi indicates the producer API that is currently connected
|
||||
// to this BufferQueue. It defaults to NO_CONNECTED_API (= 0), and gets
|
||||
// updated by the connect and disconnect methods.
|
||||
|
@ -87,7 +87,9 @@ protected:
|
||||
|
||||
// ConsumerBase constructs a new ConsumerBase object to consume image
|
||||
// buffers from the given BufferQueue.
|
||||
ConsumerBase(const sp<BufferQueue> &bufferQueue);
|
||||
// The controlledByApp flag indicates that this consumer is under the application's
|
||||
// control.
|
||||
ConsumerBase(const sp<BufferQueue> &bufferQueue, bool controlledByApp = false);
|
||||
|
||||
// onLastStrongRef gets called by RefBase just before the dtor of the most
|
||||
// derived class. It is used to clean up the buffers so that ConsumerBase
|
||||
|
@ -67,7 +67,7 @@ class CpuConsumer : public ConsumerBase
|
||||
// Create a new CPU consumer. The maxLockedBuffers parameter specifies
|
||||
// how many buffers can be locked for user access at the same time.
|
||||
CpuConsumer(const sp<BufferQueue>& bq,
|
||||
uint32_t maxLockedBuffers, bool synchronousMode = true);
|
||||
uint32_t maxLockedBuffers, bool controlledByApp = false);
|
||||
|
||||
virtual ~CpuConsumer();
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* 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_DUMMYCONSUMER_H
|
||||
#define ANDROID_GUI_DUMMYCONSUMER_H
|
||||
|
||||
#include <gui/BufferQueue.h>
|
||||
|
||||
namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
// The DummyConsumer does not keep a reference to BufferQueue
|
||||
// unlike GLConsumer. This prevents a circular reference from
|
||||
// forming without having to use a ProxyConsumerListener
|
||||
class DummyConsumer : public BufferQueue::ConsumerListener {
|
||||
public:
|
||||
DummyConsumer();
|
||||
virtual ~DummyConsumer();
|
||||
protected:
|
||||
|
||||
// Implementation of the BufferQueue::ConsumerListener interface. These
|
||||
// calls are used to notify the GLConsumer of asynchronous events in the
|
||||
// BufferQueue.
|
||||
virtual void onFrameAvailable();
|
||||
virtual void onBuffersReleased();
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
||||
#endif // ANDROID_GUI_DUMMYCONSUMER_H
|
@ -87,7 +87,7 @@ public:
|
||||
// requirement that either of these methods be called.
|
||||
GLConsumer(const sp<BufferQueue>& bq,
|
||||
GLuint tex, GLenum texTarget = GL_TEXTURE_EXTERNAL_OES,
|
||||
bool useFenceSync = true);
|
||||
bool useFenceSync = true, bool isControlledByApp = false);
|
||||
|
||||
// updateTexImage acquires the most recently queued buffer, and sets the
|
||||
// image contents of the target texture to it.
|
||||
@ -177,10 +177,6 @@ public:
|
||||
// current texture buffer.
|
||||
status_t doGLFenceWait() const;
|
||||
|
||||
// isSynchronousMode returns whether the GLConsumer is currently in
|
||||
// synchronous mode.
|
||||
bool isSynchronousMode() const;
|
||||
|
||||
// set the name of the GLConsumer that will be used to identify it in
|
||||
// log messages.
|
||||
void setName(const String8& name);
|
||||
@ -190,7 +186,6 @@ public:
|
||||
status_t setDefaultBufferFormat(uint32_t defaultFormat);
|
||||
status_t setConsumerUsageBits(uint32_t usage);
|
||||
status_t setTransformHint(uint32_t hint);
|
||||
virtual status_t setSynchronousMode(bool enabled);
|
||||
|
||||
// getBufferQueue returns the BufferQueue object to which this
|
||||
// GLConsumer is connected.
|
||||
|
@ -171,13 +171,6 @@ public:
|
||||
// 'what' tokens allowed are that of android_natives.h
|
||||
virtual int query(int what, int* value) = 0;
|
||||
|
||||
// setSynchronousMode set whether dequeueBuffer is synchronous or
|
||||
// asynchronous. In synchronous mode, dequeueBuffer blocks until
|
||||
// a buffer is available, the currently bound buffer can be dequeued and
|
||||
// queued buffers will be retired in order.
|
||||
// The default mode is asynchronous.
|
||||
virtual status_t setSynchronousMode(bool enabled) = 0;
|
||||
|
||||
// connect attempts to connect a client API to the IGraphicBufferProducer.
|
||||
// This must be called before any other IGraphicBufferProducer methods are
|
||||
// called except for getAllocator.
|
||||
@ -188,7 +181,7 @@ public:
|
||||
// outWidth, outHeight and outTransform are filled with the default width
|
||||
// and height of the window and current transform applied to buffers,
|
||||
// respectively.
|
||||
virtual status_t connect(int api, QueueBufferOutput* output) = 0;
|
||||
virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) = 0;
|
||||
|
||||
// disconnect attempts to disconnect a client API from the
|
||||
// IGraphicBufferProducer. Calling this method will cause any subsequent
|
||||
|
@ -61,8 +61,11 @@ public:
|
||||
* However, once a Surface is connected, it'll prevent other Surfaces
|
||||
* referring to the same IGraphicBufferProducer to become connected and
|
||||
* therefore prevent them to be used as actual producers of buffers.
|
||||
*
|
||||
* the controlledByApp flag indicates that this Surface (producer) is
|
||||
* controlled by the application. This flag is used at connect time.
|
||||
*/
|
||||
Surface(const sp<IGraphicBufferProducer>& bufferProducer);
|
||||
Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp = false);
|
||||
|
||||
/* getIGraphicBufferProducer() returns the IGraphicBufferProducer this
|
||||
* Surface was created with. Usually it's an error to use the
|
||||
@ -228,6 +231,10 @@ private:
|
||||
// window. this is only a hint, actual transform may differ.
|
||||
uint32_t mTransformHint;
|
||||
|
||||
// mProducerControlledByApp whether this buffer producer is controlled
|
||||
// by the application
|
||||
bool mProducerControlledByApp;
|
||||
|
||||
// mConsumerRunningBehind whether the consumer is running more than
|
||||
// one buffer behind the producer.
|
||||
mutable bool mConsumerRunningBehind;
|
||||
|
@ -8,7 +8,6 @@ LOCAL_SRC_FILES:= \
|
||||
ConsumerBase.cpp \
|
||||
CpuConsumer.cpp \
|
||||
DisplayEventReceiver.cpp \
|
||||
DummyConsumer.cpp \
|
||||
GLConsumer.cpp \
|
||||
GraphicBufferAlloc.cpp \
|
||||
GuiConfig.cpp \
|
||||
|
@ -30,11 +30,10 @@
|
||||
namespace android {
|
||||
|
||||
BufferItemConsumer::BufferItemConsumer(const sp<BufferQueue>& bq,
|
||||
uint32_t consumerUsage, int bufferCount, bool synchronousMode) :
|
||||
ConsumerBase(bq)
|
||||
uint32_t consumerUsage, int bufferCount, bool controlledByApp) :
|
||||
ConsumerBase(bq, controlledByApp)
|
||||
{
|
||||
mBufferQueue->setConsumerUsageBits(consumerUsage);
|
||||
mBufferQueue->setSynchronousMode(synchronousMode);
|
||||
mBufferQueue->setMaxAcquiredBufferCount(bufferCount);
|
||||
}
|
||||
|
||||
|
@ -63,15 +63,15 @@ static const char* scalingModeName(int scalingMode) {
|
||||
}
|
||||
}
|
||||
|
||||
BufferQueue::BufferQueue(bool allowSynchronousMode,
|
||||
const sp<IGraphicBufferAlloc>& allocator) :
|
||||
BufferQueue::BufferQueue(const sp<IGraphicBufferAlloc>& allocator) :
|
||||
mDefaultWidth(1),
|
||||
mDefaultHeight(1),
|
||||
mMaxAcquiredBufferCount(1),
|
||||
mDefaultMaxBufferCount(2),
|
||||
mOverrideMaxBufferCount(0),
|
||||
mSynchronousMode(false),
|
||||
mAllowSynchronousMode(allowSynchronousMode),
|
||||
mConsumerControlledByApp(false),
|
||||
mDequeueBufferCannotBlock(false),
|
||||
mSynchronousMode(true),
|
||||
mConnectedApi(NO_CONNECTED_API),
|
||||
mAbandoned(false),
|
||||
mFrameCounter(0),
|
||||
@ -109,11 +109,6 @@ status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool BufferQueue::isSynchronousMode() const {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mSynchronousMode;
|
||||
}
|
||||
|
||||
void BufferQueue::setConsumerName(const String8& name) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
mConsumerName = name;
|
||||
@ -348,6 +343,10 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence,
|
||||
// the max buffer count to change.
|
||||
tryAgain = found == INVALID_BUFFER_SLOT;
|
||||
if (tryAgain) {
|
||||
if (mDequeueBufferCannotBlock) {
|
||||
ST_LOGE("dequeueBuffer: would block! returning an error instead.");
|
||||
return WOULD_BLOCK;
|
||||
}
|
||||
mDequeueCondition.wait(mMutex);
|
||||
}
|
||||
}
|
||||
@ -441,38 +440,6 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence,
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
status_t BufferQueue::setSynchronousMode(bool enabled) {
|
||||
ATRACE_CALL();
|
||||
ST_LOGV("setSynchronousMode: enabled=%d", enabled);
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
if (mAbandoned) {
|
||||
ST_LOGE("setSynchronousMode: BufferQueue has been abandoned!");
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
status_t err = OK;
|
||||
if (!mAllowSynchronousMode && enabled)
|
||||
return err;
|
||||
|
||||
if (!enabled) {
|
||||
// going to asynchronous mode, drain the queue
|
||||
err = drainQueueLocked();
|
||||
if (err != NO_ERROR)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (mSynchronousMode != enabled) {
|
||||
// - if we're going to asynchronous mode, the queue is guaranteed to be
|
||||
// empty here
|
||||
// - if the client set the number of buffers, we're guaranteed that
|
||||
// we have at least 3 (because we don't allow less)
|
||||
mSynchronousMode = enabled;
|
||||
mDequeueCondition.broadcast();
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
status_t BufferQueue::queueBuffer(int buf,
|
||||
const QueueBufferInput& input, QueueBufferOutput* output) {
|
||||
ATRACE_CALL();
|
||||
@ -630,7 +597,7 @@ void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) {
|
||||
mDequeueCondition.broadcast();
|
||||
}
|
||||
|
||||
status_t BufferQueue::connect(int api, QueueBufferOutput* output) {
|
||||
status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBufferOutput* output) {
|
||||
ATRACE_CALL();
|
||||
ST_LOGV("connect: api=%d", api);
|
||||
Mutex::Autolock lock(mMutex);
|
||||
@ -667,6 +634,8 @@ status_t BufferQueue::connect(int api, QueueBufferOutput* output) {
|
||||
}
|
||||
|
||||
mBufferHasBeenQueued = false;
|
||||
mDequeueBufferCannotBlock = mConsumerControlledByApp && producerControlledByApp;
|
||||
mSynchronousMode = !mDequeueBufferCannotBlock;
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -950,7 +919,8 @@ status_t BufferQueue::releaseBuffer(
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) {
|
||||
status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener,
|
||||
bool controlledByApp) {
|
||||
ST_LOGV("consumerConnect");
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
@ -964,6 +934,7 @@ status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListen
|
||||
}
|
||||
|
||||
mConsumerListener = consumerListener;
|
||||
mConsumerControlledByApp = controlledByApp;
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ static int32_t createProcessUniqueId() {
|
||||
return android_atomic_inc(&globalCounter);
|
||||
}
|
||||
|
||||
ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) :
|
||||
ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue, bool controlledByApp) :
|
||||
mAbandoned(false),
|
||||
mBufferQueue(bufferQueue) {
|
||||
// Choose a name using the PID and a process-unique ID.
|
||||
@ -66,7 +66,7 @@ ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) :
|
||||
listener = static_cast<BufferQueue::ConsumerListener*>(this);
|
||||
proxy = new BufferQueue::ProxyConsumerListener(listener);
|
||||
|
||||
status_t err = mBufferQueue->consumerConnect(proxy);
|
||||
status_t err = mBufferQueue->consumerConnect(proxy, controlledByApp);
|
||||
if (err != NO_ERROR) {
|
||||
CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
|
||||
strerror(-err), err);
|
||||
|
@ -31,15 +31,14 @@
|
||||
namespace android {
|
||||
|
||||
CpuConsumer::CpuConsumer(const sp<BufferQueue>& bq,
|
||||
uint32_t maxLockedBuffers, bool synchronousMode) :
|
||||
ConsumerBase(bq),
|
||||
uint32_t maxLockedBuffers, bool controlledByApp) :
|
||||
ConsumerBase(bq, controlledByApp),
|
||||
mMaxLockedBuffers(maxLockedBuffers),
|
||||
mCurrentLockedBuffers(0)
|
||||
{
|
||||
// Create tracking entries for locked buffers
|
||||
mAcquiredBuffers.insertAt(0, maxLockedBuffers);
|
||||
|
||||
mBufferQueue->setSynchronousMode(synchronousMode);
|
||||
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
|
||||
mBufferQueue->setMaxAcquiredBufferCount(maxLockedBuffers);
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* 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_TAG "DummyConsumer"
|
||||
// #define LOG_NDEBUG 0
|
||||
|
||||
#include <gui/DummyConsumer.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
DummyConsumer::DummyConsumer() {
|
||||
ALOGV("DummyConsumer");
|
||||
}
|
||||
|
||||
DummyConsumer::~DummyConsumer() {
|
||||
ALOGV("~DummyConsumer");
|
||||
}
|
||||
|
||||
void DummyConsumer::onFrameAvailable() {
|
||||
ALOGV("onFrameAvailable");
|
||||
}
|
||||
|
||||
void DummyConsumer::onBuffersReleased() {
|
||||
ALOGV("onBuffersReleased");
|
||||
}
|
||||
|
||||
}; // namespace android
|
@ -79,8 +79,8 @@ static void mtxMul(float out[16], const float a[16], const float b[16]);
|
||||
|
||||
|
||||
GLConsumer::GLConsumer(const sp<BufferQueue>& bq, GLuint tex,
|
||||
GLenum texTarget, bool useFenceSync) :
|
||||
ConsumerBase(bq),
|
||||
GLenum texTarget, bool useFenceSync, bool isControlledByApp) :
|
||||
ConsumerBase(bq, isControlledByApp),
|
||||
mCurrentTransform(0),
|
||||
mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
|
||||
mCurrentFence(Fence::NO_FENCE),
|
||||
@ -844,11 +844,6 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
bool GLConsumer::isSynchronousMode() const {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->isSynchronousMode();
|
||||
}
|
||||
|
||||
void GLConsumer::freeBufferLocked(int slotIndex) {
|
||||
ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
|
||||
if (slotIndex == mCurrentTexture) {
|
||||
@ -891,13 +886,6 @@ status_t GLConsumer::setTransformHint(uint32_t hint) {
|
||||
return mBufferQueue->setTransformHint(hint);
|
||||
}
|
||||
|
||||
// Used for refactoring BufferQueue from GLConsumer
|
||||
// Should not be in final interface once users of GLConsumer are clean up.
|
||||
status_t GLConsumer::setSynchronousMode(bool enabled) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->setSynchronousMode(enabled);
|
||||
}
|
||||
|
||||
void GLConsumer::dumpLocked(String8& result, const char* prefix) const
|
||||
{
|
||||
result.appendFormat(
|
||||
|
@ -37,7 +37,6 @@ enum {
|
||||
QUEUE_BUFFER,
|
||||
CANCEL_BUFFER,
|
||||
QUERY,
|
||||
SET_SYNCHRONOUS_MODE,
|
||||
CONNECT,
|
||||
DISCONNECT,
|
||||
};
|
||||
@ -142,22 +141,11 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual status_t setSynchronousMode(bool enabled) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
|
||||
data.writeInt32(enabled);
|
||||
status_t result = remote()->transact(SET_SYNCHRONOUS_MODE, data, &reply);
|
||||
if (result != NO_ERROR) {
|
||||
return result;
|
||||
}
|
||||
result = reply.readInt32();
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual status_t connect(int api, QueueBufferOutput* output) {
|
||||
virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output) {
|
||||
Parcel data, reply;
|
||||
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
|
||||
data.writeInt32(api);
|
||||
data.writeInt32(producerControlledByApp);
|
||||
status_t result = remote()->transact(CONNECT, data, &reply);
|
||||
if (result != NO_ERROR) {
|
||||
return result;
|
||||
@ -252,20 +240,14 @@ status_t BnGraphicBufferProducer::onTransact(
|
||||
reply->writeInt32(res);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
case SET_SYNCHRONOUS_MODE: {
|
||||
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
|
||||
bool enabled = data.readInt32();
|
||||
status_t res = setSynchronousMode(enabled);
|
||||
reply->writeInt32(res);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
case CONNECT: {
|
||||
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
|
||||
int api = data.readInt32();
|
||||
bool producerControlledByApp = data.readInt32();
|
||||
QueueBufferOutput* const output =
|
||||
reinterpret_cast<QueueBufferOutput *>(
|
||||
reply->writeInplace(sizeof(QueueBufferOutput)));
|
||||
status_t res = connect(api, output);
|
||||
status_t res = connect(api, producerControlledByApp, output);
|
||||
reply->writeInt32(res);
|
||||
return NO_ERROR;
|
||||
} break;
|
||||
|
@ -37,7 +37,8 @@
|
||||
namespace android {
|
||||
|
||||
Surface::Surface(
|
||||
const sp<IGraphicBufferProducer>& bufferProducer)
|
||||
const sp<IGraphicBufferProducer>& bufferProducer,
|
||||
bool controlledByApp)
|
||||
: mGraphicBufferProducer(bufferProducer)
|
||||
{
|
||||
// Initialize the ANativeWindow function pointers.
|
||||
@ -71,6 +72,7 @@ Surface::Surface(
|
||||
mTransformHint = 0;
|
||||
mConsumerRunningBehind = false;
|
||||
mConnectedToCpu = false;
|
||||
mProducerControlledByApp = true;
|
||||
}
|
||||
|
||||
Surface::~Surface() {
|
||||
@ -168,7 +170,9 @@ int Surface::setSwapInterval(int interval) {
|
||||
if (interval > maxSwapInterval)
|
||||
interval = maxSwapInterval;
|
||||
|
||||
status_t res = mGraphicBufferProducer->setSynchronousMode(interval ? true : false);
|
||||
// FIXME: re-implement swap-interval
|
||||
//status_t res = mGraphicBufferProducer->setSynchronousMode(interval ? true : false);
|
||||
status_t res = NO_ERROR;
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -486,7 +490,7 @@ int Surface::connect(int api) {
|
||||
ALOGV("Surface::connect");
|
||||
Mutex::Autolock lock(mMutex);
|
||||
IGraphicBufferProducer::QueueBufferOutput output;
|
||||
int err = mGraphicBufferProducer->connect(api, &output);
|
||||
int err = mGraphicBufferProducer->connect(api, mProducerControlledByApp, &output);
|
||||
if (err == NO_ERROR) {
|
||||
uint32_t numPendingBuffers = 0;
|
||||
output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
|
||||
|
@ -62,9 +62,9 @@ struct DummyConsumer : public BufferQueue::ConsumerListener {
|
||||
|
||||
TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
|
||||
sp<DummyConsumer> dc(new DummyConsumer);
|
||||
mBQ->consumerConnect(dc);
|
||||
mBQ->consumerConnect(dc, false);
|
||||
IGraphicBufferProducer::QueueBufferOutput qbo;
|
||||
mBQ->connect(NATIVE_WINDOW_API_CPU, &qbo);
|
||||
mBQ->connect(NATIVE_WINDOW_API_CPU, false, &qbo);
|
||||
mBQ->setBufferCount(4);
|
||||
|
||||
int slot;
|
||||
@ -95,7 +95,7 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
|
||||
|
||||
TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError) {
|
||||
sp<DummyConsumer> dc(new DummyConsumer);
|
||||
mBQ->consumerConnect(dc);
|
||||
mBQ->consumerConnect(dc, false);
|
||||
|
||||
ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(0));
|
||||
ASSERT_EQ(BAD_VALUE, mBQ->setMaxAcquiredBufferCount(-3));
|
||||
@ -106,7 +106,7 @@ TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithIllegalValues_ReturnsError)
|
||||
|
||||
TEST_F(BufferQueueTest, SetMaxAcquiredBufferCountWithLegalValues_Succeeds) {
|
||||
sp<DummyConsumer> dc(new DummyConsumer);
|
||||
mBQ->consumerConnect(dc);
|
||||
mBQ->consumerConnect(dc, false);
|
||||
|
||||
ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount(1));
|
||||
ASSERT_EQ(OK, mBQ->setMaxAcquiredBufferCount(2));
|
||||
|
@ -338,7 +338,7 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
|
||||
|
||||
TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
|
||||
android_native_buffer_t* buf[3];
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(false));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 0));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
|
||||
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
|
||||
@ -346,7 +346,7 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
|
||||
EXPECT_EQ(OK, mST->updateTexImage());
|
||||
EXPECT_EQ(OK, mST->updateTexImage());
|
||||
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
|
||||
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
|
||||
@ -361,7 +361,7 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) {
|
||||
|
||||
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
|
||||
android_native_buffer_t* buf[3];
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
|
||||
@ -382,7 +382,7 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) {
|
||||
|
||||
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
|
||||
android_native_buffer_t* buf[3];
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
|
||||
@ -403,7 +403,7 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) {
|
||||
|
||||
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
|
||||
android_native_buffer_t* buf[3];
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
|
||||
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
|
||||
@ -429,7 +429,7 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) {
|
||||
TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) {
|
||||
android_native_buffer_t* buf[3];
|
||||
android_native_buffer_t* firstBuf;
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &firstBuf));
|
||||
ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf, -1));
|
||||
@ -449,7 +449,7 @@ TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent)
|
||||
|
||||
TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
|
||||
android_native_buffer_t* buf[3];
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
|
||||
|
||||
// We should be able to dequeue all the buffers before we've queued mANWy.
|
||||
@ -528,7 +528,7 @@ TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) {
|
||||
};
|
||||
|
||||
android_native_buffer_t* buf[3];
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mANW->setSwapInterval(mANW.get(), 1));
|
||||
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3));
|
||||
// dequeue/queue/update so we have a current buffer
|
||||
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
|
||||
|
@ -944,7 +944,6 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
|
||||
enum { texHeight = 16 };
|
||||
enum { numFrames = 1024 };
|
||||
|
||||
ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
|
||||
ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
|
||||
texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
|
||||
@ -1211,10 +1210,8 @@ TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
|
||||
sp<ANativeWindow> mANW;
|
||||
};
|
||||
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
|
||||
sp<DisconnectWaiter> dw(new DisconnectWaiter());
|
||||
mST->getBufferQueue()->consumerConnect(dw);
|
||||
mST->getBufferQueue()->consumerConnect(dw, false);
|
||||
|
||||
|
||||
sp<Thread> pt(new ProducerThread(mANW));
|
||||
@ -1237,8 +1234,6 @@ TEST_F(SurfaceTextureGLTest, DisconnectStressTest) {
|
||||
// when it is disconnected and reconnected. Otherwise it will
|
||||
// attempt to release a buffer that it does not owned
|
||||
TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
|
||||
ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
|
||||
NATIVE_WINDOW_API_EGL));
|
||||
|
||||
@ -1258,8 +1253,6 @@ TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
|
||||
ASSERT_EQ(OK, native_window_api_connect(mANW.get(),
|
||||
NATIVE_WINDOW_API_EGL));
|
||||
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
|
||||
EXPECT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &anb));
|
||||
EXPECT_EQ(OK, mANW->queueBuffer(mANW.get(), anb, -1));
|
||||
|
||||
@ -1272,8 +1265,6 @@ TEST_F(SurfaceTextureGLTest, DisconnectClearsCurrentTexture) {
|
||||
}
|
||||
|
||||
TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
|
||||
ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
|
||||
NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW));
|
||||
|
||||
@ -1306,8 +1297,6 @@ TEST_F(SurfaceTextureGLTest, ScaleToWindowMode) {
|
||||
// the image such that it has the same aspect ratio as the
|
||||
// default buffer size
|
||||
TEST_F(SurfaceTextureGLTest, CroppedScalingMode) {
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
|
||||
ASSERT_EQ(OK, native_window_set_scaling_mode(mANW.get(),
|
||||
NATIVE_WINDOW_SCALING_MODE_SCALE_CROP));
|
||||
|
||||
@ -1417,7 +1406,6 @@ TEST_F(SurfaceTextureGLTest, AbandonUnblocksDequeueBuffer) {
|
||||
Mutex mMutex;
|
||||
};
|
||||
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
|
||||
|
||||
sp<Thread> pt(new ProducerThread(mANW));
|
||||
@ -1810,32 +1798,6 @@ TEST_F(SurfaceTextureGLToGLTest, EglMakeCurrentAfterConsumerDeathUnrefsBuffers)
|
||||
EXPECT_EQ(1, buffer->getStrongCount());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(SurfaceTextureGLToGLTest, EglSurfaceDefaultsToSynchronousMode) {
|
||||
// This test requires 3 buffers to run on a single thread.
|
||||
mST->setDefaultMaxBufferCount(3);
|
||||
|
||||
ASSERT_TRUE(mST->isSynchronousMode());
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
// Produce a frame
|
||||
EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mProducerEglSurface,
|
||||
mProducerEglSurface, mProducerEglContext));
|
||||
ASSERT_EQ(EGL_SUCCESS, eglGetError());
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
EXPECT_TRUE(eglSwapBuffers(mEglDisplay, mProducerEglSurface));
|
||||
ASSERT_EQ(EGL_SUCCESS, eglGetError());
|
||||
|
||||
// Consume a frame
|
||||
EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface,
|
||||
mEglContext));
|
||||
ASSERT_EQ(EGL_SUCCESS, eglGetError());
|
||||
ASSERT_EQ(NO_ERROR, mST->updateTexImage());
|
||||
}
|
||||
|
||||
ASSERT_TRUE(mST->isSynchronousMode());
|
||||
}
|
||||
|
||||
TEST_F(SurfaceTextureGLToGLTest, TexturingFromUserSizedGLFilledBuffer) {
|
||||
enum { texWidth = 64 };
|
||||
enum { texHeight = 64 };
|
||||
@ -2285,7 +2247,6 @@ TEST_F(SurfaceTextureGLThreadToGLTest,
|
||||
}
|
||||
};
|
||||
|
||||
ASSERT_EQ(OK, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(OK, mST->setDefaultMaxBufferCount(2));
|
||||
|
||||
runProducerThread(new PT());
|
||||
@ -2826,7 +2787,6 @@ TEST_F(SurfaceTextureMultiContextGLTest,
|
||||
|
||||
TEST_F(SurfaceTextureMultiContextGLTest,
|
||||
UpdateTexImageSucceedsForBufferConsumedBeforeDetach) {
|
||||
ASSERT_EQ(NO_ERROR, mST->setSynchronousMode(true));
|
||||
ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
|
||||
|
||||
// produce two frames and consume them both on the primary context
|
||||
|
@ -83,7 +83,9 @@ TEST_F(SurfaceTest, QueuesToWindowComposerIsTrueWhenPurgatorized) {
|
||||
}
|
||||
|
||||
// This test probably doesn't belong here.
|
||||
TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) {
|
||||
// DISABLED because it hangs when disconnecting because of draining the queue.
|
||||
// will be fixed in a subsequent BQ change
|
||||
TEST_F(SurfaceTest, DISABLED_ScreenshotsOfProtectedBuffersSucceed) {
|
||||
sp<ANativeWindow> anw(mSurface);
|
||||
|
||||
// Verify the screenshot works with no protected buffers.
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <gui/Surface.h>
|
||||
#include <gui/DummyConsumer.h>
|
||||
|
||||
|
||||
namespace android {
|
||||
@ -101,9 +100,14 @@ TEST_F(EGLTest, EGLTerminateSucceedsWithRemainingObjects) {
|
||||
};
|
||||
EXPECT_TRUE(eglChooseConfig(mEglDisplay, attrs, &config, 1, &numConfigs));
|
||||
|
||||
struct DummyConsumer : public BufferQueue::ConsumerListener {
|
||||
virtual void onFrameAvailable() {}
|
||||
virtual void onBuffersReleased() {}
|
||||
};
|
||||
|
||||
// Create a EGLSurface
|
||||
sp<BufferQueue> bq = new BufferQueue();
|
||||
bq->consumerConnect(new DummyConsumer());
|
||||
bq->consumerConnect(new DummyConsumer, false);
|
||||
sp<Surface> mSTC = new Surface(static_cast<sp<IGraphicBufferProducer> >( bq));
|
||||
sp<ANativeWindow> mANW = mSTC;
|
||||
|
||||
|
@ -36,7 +36,6 @@ ifeq ($(TARGET_BOARD_PLATFORM),omap4)
|
||||
endif
|
||||
ifeq ($(TARGET_BOARD_PLATFORM),s5pc110)
|
||||
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
|
||||
LOCAL_CFLAGS += -DNEVER_DEFAULT_TO_ASYNC_MODE
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_DISABLE_TRIPLE_BUFFERING),true)
|
||||
|
@ -51,7 +51,7 @@ namespace android {
|
||||
*/
|
||||
|
||||
FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) :
|
||||
ConsumerBase(new BufferQueue(true, new GraphicBufferAlloc())),
|
||||
ConsumerBase(new BufferQueue(new GraphicBufferAlloc())),
|
||||
mDisplayType(disp),
|
||||
mCurrentBufferSlot(-1),
|
||||
mCurrentBuffer(0),
|
||||
@ -64,7 +64,6 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc, int disp) :
|
||||
GRALLOC_USAGE_HW_COMPOSER);
|
||||
mBufferQueue->setDefaultBufferFormat(mHwc.getFormat(disp));
|
||||
mBufferQueue->setDefaultBufferSize(mHwc.getWidth(disp), mHwc.getHeight(disp));
|
||||
mBufferQueue->setSynchronousMode(true);
|
||||
mBufferQueue->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS);
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ static const char* dbgCompositionTypeStr(DisplaySurface::CompositionType type) {
|
||||
|
||||
VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, int32_t dispId,
|
||||
const sp<IGraphicBufferProducer>& sink, const String8& name)
|
||||
: ConsumerBase(new BufferQueue(true)),
|
||||
: ConsumerBase(new BufferQueue()),
|
||||
mHwc(hwc),
|
||||
mDisplayId(dispId),
|
||||
mDisplayName(name),
|
||||
@ -345,13 +345,10 @@ int VirtualDisplaySurface::query(int what, int* value) {
|
||||
return mSource[SOURCE_SINK]->query(what, value);
|
||||
}
|
||||
|
||||
status_t VirtualDisplaySurface::setSynchronousMode(bool enabled) {
|
||||
return mSource[SOURCE_SINK]->setSynchronousMode(enabled);
|
||||
}
|
||||
|
||||
status_t VirtualDisplaySurface::connect(int api, QueueBufferOutput* output) {
|
||||
status_t VirtualDisplaySurface::connect(int api, bool producerControlledByApp,
|
||||
QueueBufferOutput* output) {
|
||||
QueueBufferOutput qbo;
|
||||
status_t result = mSource[SOURCE_SINK]->connect(api, &qbo);
|
||||
status_t result = mSource[SOURCE_SINK]->connect(api, producerControlledByApp, &qbo);
|
||||
if (result == NO_ERROR) {
|
||||
updateQueueBufferOutput(qbo);
|
||||
*output = mQueueBufferOutput;
|
||||
|
@ -101,8 +101,7 @@ private:
|
||||
const QueueBufferInput& input, QueueBufferOutput* output);
|
||||
virtual void cancelBuffer(int pslot, const sp<Fence>& fence);
|
||||
virtual int query(int what, int* value);
|
||||
virtual status_t setSynchronousMode(bool enabled);
|
||||
virtual status_t connect(int api, QueueBufferOutput* output);
|
||||
virtual status_t connect(int api, bool producerControlledByApp, QueueBufferOutput* output);
|
||||
virtual status_t disconnect(int api);
|
||||
|
||||
//
|
||||
|
@ -115,7 +115,6 @@ void Layer::onFirstRef()
|
||||
|
||||
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
|
||||
mSurfaceFlingerConsumer->setFrameAvailableListener(this);
|
||||
mSurfaceFlingerConsumer->setSynchronousMode(true);
|
||||
mSurfaceFlingerConsumer->setName(mName);
|
||||
|
||||
#ifdef TARGET_DISABLE_TRIPLE_BUFFERING
|
||||
|
@ -28,7 +28,7 @@ namespace android {
|
||||
|
||||
|
||||
SurfaceTextureLayer::SurfaceTextureLayer(const sp<SurfaceFlinger>& flinger)
|
||||
: BufferQueue(true), flinger(flinger) {
|
||||
: BufferQueue(), flinger(flinger) {
|
||||
}
|
||||
|
||||
SurfaceTextureLayer::~SurfaceTextureLayer() {
|
||||
@ -51,32 +51,5 @@ SurfaceTextureLayer::~SurfaceTextureLayer() {
|
||||
flinger->postMessageAsync( new MessageCleanUpList(flinger, this) );
|
||||
}
|
||||
|
||||
status_t SurfaceTextureLayer::connect(int api, QueueBufferOutput* output) {
|
||||
status_t err = BufferQueue::connect(api, output);
|
||||
if (err == NO_ERROR) {
|
||||
switch(api) {
|
||||
case NATIVE_WINDOW_API_MEDIA:
|
||||
case NATIVE_WINDOW_API_CAMERA:
|
||||
// Camera preview and videos are rate-limited on the producer
|
||||
// side. If enabled for this build, we use async mode to always
|
||||
// show the most recent frame at the cost of requiring an
|
||||
// additional buffer.
|
||||
#ifndef NEVER_DEFAULT_TO_ASYNC_MODE
|
||||
err = setSynchronousMode(false);
|
||||
break;
|
||||
#endif
|
||||
// fall through to set synchronous mode when not defaulting to
|
||||
// async mode.
|
||||
default:
|
||||
err = setSynchronousMode(true);
|
||||
break;
|
||||
}
|
||||
if (err != NO_ERROR) {
|
||||
disconnect(api);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
|
@ -38,10 +38,6 @@ class SurfaceTextureLayer : public BufferQueue {
|
||||
public:
|
||||
SurfaceTextureLayer(const sp<SurfaceFlinger>& flinger);
|
||||
virtual ~SurfaceTextureLayer();
|
||||
|
||||
// After calling the superclass connect(), set or clear synchronous
|
||||
// mode appropriately for the specified API.
|
||||
virtual status_t connect(int api, QueueBufferOutput* output);
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user