SurfaceTexture: Fully refactored from BufferQueue
SurfaceTexture and BufferQueue are separate objects. Change-Id: I230bc0ae6f78d0f9b2b5df902f40ab443ed5a055
This commit is contained in:
parent
fddc28d871
commit
b267579ba8
@ -203,6 +203,16 @@ public:
|
||||
// when a new frame becomes available.
|
||||
void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);
|
||||
|
||||
// setDefaultBufferFormat allows the BufferQueue to create
|
||||
// GraphicBuffers of a defaultFormat if no format is specified
|
||||
// in dequeueBuffer
|
||||
status_t setDefaultBufferFormat(uint32_t defaultFormat);
|
||||
|
||||
// setConsumerUsageBits will turn on additional usage bits for dequeueBuffer
|
||||
status_t setConsumerUsageBits(uint32_t usage);
|
||||
|
||||
// setTransformHint bakes in rotation to buffers so overlays can be used
|
||||
status_t setTransformHint(uint32_t hint);
|
||||
|
||||
private:
|
||||
// freeBufferLocked frees the resources (both GraphicBuffer and EGLImage)
|
||||
@ -417,7 +427,19 @@ private:
|
||||
// with the surface Texture.
|
||||
uint64_t mFrameCounter;
|
||||
|
||||
// mBufferHasBeenQueued is true once a buffer has been queued. It is reset
|
||||
// by changing the buffer count.
|
||||
bool mBufferHasBeenQueued;
|
||||
|
||||
// mDefaultBufferFormat can be set so it will override
|
||||
// the buffer format when it isn't specified in dequeueBuffer
|
||||
uint32_t mDefaultBufferFormat;
|
||||
|
||||
// mConsumerUsageBits contains flags the consumer wants for GraphicBuffers
|
||||
uint32_t mConsumerUsageBits;
|
||||
|
||||
// mTransformHint is used to optimize for screen rotations
|
||||
uint32_t mTransformHint;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -39,8 +39,12 @@ namespace android {
|
||||
|
||||
class String8;
|
||||
|
||||
class SurfaceTexture : public BufferQueue {
|
||||
class SurfaceTexture : public virtual RefBase {
|
||||
public:
|
||||
// This typedef allows external code to continue referencing
|
||||
// SurfaceTexture::FrameAvailableListener during refactoring
|
||||
typedef BufferQueue::FrameAvailableListener FrameAvailableListener;
|
||||
|
||||
|
||||
// SurfaceTexture constructs a new SurfaceTexture object. tex indicates the
|
||||
// name of the OpenGL ES texture to which images are to be streamed. This
|
||||
@ -49,14 +53,15 @@ public:
|
||||
// enabled. texTarget specifies the OpenGL ES texture target to which the
|
||||
// texture will be bound in updateTexImage. useFenceSync specifies whether
|
||||
// fences should be used to synchronize access to buffers if that behavior
|
||||
// is enabled at compile-time.
|
||||
// is enabled at compile-time. A custom bufferQueue can be specified
|
||||
// if behavior for queue/dequeue/connect etc needs to be customized.
|
||||
// Otherwise a default BufferQueue will be created and used.
|
||||
SurfaceTexture(GLuint tex, bool allowSynchronousMode = true,
|
||||
GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true);
|
||||
GLenum texTarget = GL_TEXTURE_EXTERNAL_OES, bool useFenceSync = true,
|
||||
const sp<BufferQueue> &bufferQueue = 0);
|
||||
|
||||
virtual ~SurfaceTexture();
|
||||
|
||||
|
||||
|
||||
// updateTexImage sets the image contents of the target texture to that of
|
||||
// the most recently queued buffer.
|
||||
//
|
||||
@ -152,6 +157,18 @@ public:
|
||||
// log messages.
|
||||
void setName(const String8& name);
|
||||
|
||||
// These functions call the corresponding BufferQueue implementation
|
||||
// so the refactoring can proceed smoothly
|
||||
status_t setDefaultBufferFormat(uint32_t defaultFormat);
|
||||
status_t setConsumerUsageBits(uint32_t usage);
|
||||
status_t setTransformHint(uint32_t hint);
|
||||
virtual status_t setSynchronousMode(bool enabled);
|
||||
virtual status_t setBufferCount(int bufferCount);
|
||||
virtual status_t connect(int api,
|
||||
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
|
||||
|
||||
sp<BufferQueue> getBufferQueue() const;
|
||||
|
||||
// dump our state in a String
|
||||
virtual void dump(String8& result) const;
|
||||
virtual void dump(String8& result, const char* prefix, char* buffer, size_t SIZE) const;
|
||||
@ -241,7 +258,7 @@ private:
|
||||
EGLSyncKHR mFence;
|
||||
};
|
||||
|
||||
EGLSlot mEGLSlots[NUM_BUFFER_SLOTS];
|
||||
EGLSlot mEGLSlots[BufferQueue::NUM_BUFFER_SLOTS];
|
||||
|
||||
// mAbandoned indicates that the BufferQueue will no longer be used to
|
||||
// consume images buffers pushed to it using the ISurfaceTexture interface.
|
||||
@ -267,6 +284,10 @@ private:
|
||||
// reset mCurrentTexture to INVALID_BUFFER_SLOT.
|
||||
int mCurrentTexture;
|
||||
|
||||
// The SurfaceTexture has-a BufferQueue and is responsible for creating this object
|
||||
// if none is supplied
|
||||
sp<BufferQueue> mBufferQueue;
|
||||
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <gui/ISurfaceTexture.h>
|
||||
#include <gui/SurfaceTexture.h>
|
||||
#include <gui/BufferQueue.h>
|
||||
|
||||
#include <ui/ANativeObjectBase.h>
|
||||
#include <ui/Region.h>
|
||||
@ -34,8 +35,15 @@ class SurfaceTextureClient
|
||||
: public ANativeObjectBase<ANativeWindow, SurfaceTextureClient, RefBase>
|
||||
{
|
||||
public:
|
||||
|
||||
SurfaceTextureClient(const sp<ISurfaceTexture>& surfaceTexture);
|
||||
|
||||
// SurfaceTextureClient is overloaded to assist in refactoring ST and BQ.
|
||||
// SurfaceTexture is no longer an ISurfaceTexture, so client code
|
||||
// calling the original constructor will fail. Thus this convenience method
|
||||
// passes in the surfaceTexture's bufferQueue to the init method.
|
||||
SurfaceTextureClient(const sp<SurfaceTexture>& surfaceTexture);
|
||||
|
||||
sp<ISurfaceTexture> getISurfaceTexture() const;
|
||||
|
||||
protected:
|
||||
@ -94,8 +102,8 @@ protected:
|
||||
virtual int lock(ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
|
||||
virtual int unlockAndPost();
|
||||
|
||||
enum { MIN_UNDEQUEUED_BUFFERS = SurfaceTexture::MIN_UNDEQUEUED_BUFFERS };
|
||||
enum { NUM_BUFFER_SLOTS = SurfaceTexture::NUM_BUFFER_SLOTS };
|
||||
enum { MIN_UNDEQUEUED_BUFFERS = BufferQueue::MIN_UNDEQUEUED_BUFFERS };
|
||||
enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };
|
||||
enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 };
|
||||
|
||||
private:
|
||||
|
@ -83,7 +83,10 @@ BufferQueue::BufferQueue( bool allowSynchronousMode ) :
|
||||
mConnectedApi(NO_CONNECTED_API),
|
||||
mAbandoned(false),
|
||||
mFrameCounter(0),
|
||||
mBufferHasBeenQueued(false)
|
||||
mBufferHasBeenQueued(false),
|
||||
mDefaultBufferFormat(0),
|
||||
mConsumerUsageBits(0),
|
||||
mTransformHint(0)
|
||||
{
|
||||
// Choose a name using the PID and a process-unique ID.
|
||||
mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
|
||||
@ -128,6 +131,7 @@ status_t BufferQueue::setBufferCountServerLocked(int bufferCount) {
|
||||
// dequeueBuffer.
|
||||
|
||||
mServerBufferCount = bufferCount;
|
||||
mDequeueCondition.broadcast();
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@ -149,6 +153,24 @@ void BufferQueue::setFrameAvailableListener(
|
||||
mFrameAvailableListener = listener;
|
||||
}
|
||||
|
||||
status_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
mDefaultBufferFormat = defaultFormat;
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t BufferQueue::setConsumerUsageBits(uint32_t usage) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
mConsumerUsageBits = usage;
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t BufferQueue::setTransformHint(uint32_t hint) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
mTransformHint = hint;
|
||||
return OK;
|
||||
}
|
||||
|
||||
status_t BufferQueue::setBufferCount(int bufferCount) {
|
||||
ST_LOGV("setBufferCount: count=%d", bufferCount);
|
||||
Mutex::Autolock lock(mMutex);
|
||||
@ -263,6 +285,12 @@ status_t BufferQueue::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h,
|
||||
{ // Scope for the lock
|
||||
Mutex::Autolock lock(mMutex);
|
||||
|
||||
if (format == 0) {
|
||||
format = mDefaultBufferFormat;
|
||||
}
|
||||
// turn on usage bits the consumer requested
|
||||
usage |= mConsumerUsageBits;
|
||||
|
||||
int found = -1;
|
||||
int foundSync = -1;
|
||||
int dequeuedCount = 0;
|
||||
@ -563,7 +591,7 @@ status_t BufferQueue::queueBuffer(int buf, int64_t timestamp,
|
||||
|
||||
*outWidth = mDefaultWidth;
|
||||
*outHeight = mDefaultHeight;
|
||||
*outTransform = 0;
|
||||
*outTransform = mTransformHint;
|
||||
|
||||
ATRACE_INT(mConsumerName.string(), mQueue.size());
|
||||
} // scope for the lock
|
||||
@ -846,7 +874,8 @@ status_t BufferQueue::acquire(BufferItem *buffer) {
|
||||
ATRACE_INT(mConsumerName.string(), mQueue.size());
|
||||
}
|
||||
else {
|
||||
return -EINVAL; //should be a better return code
|
||||
// should be a better return code?
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -880,9 +909,10 @@ status_t BufferQueue::releaseBuffer(int buf, EGLDisplay display,
|
||||
|
||||
status_t BufferQueue::consumerDisconnect() {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
// Once the SurfaceTexture disconnects, the BufferQueue
|
||||
// is considered abandoned
|
||||
|
||||
mAbandoned = true;
|
||||
|
||||
mQueue.clear();
|
||||
freeAllBuffersLocked();
|
||||
mDequeueCondition.broadcast();
|
||||
return OK;
|
||||
|
@ -105,8 +105,7 @@ static int32_t createProcessUniqueId() {
|
||||
}
|
||||
|
||||
SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
|
||||
GLenum texTarget, bool useFenceSync) :
|
||||
BufferQueue(allowSynchronousMode),
|
||||
GLenum texTarget, bool useFenceSync, const sp<BufferQueue> &bufferQueue) :
|
||||
mCurrentTransform(0),
|
||||
mCurrentTimestamp(0),
|
||||
mTexName(tex),
|
||||
@ -121,27 +120,37 @@ SurfaceTexture::SurfaceTexture(GLuint tex, bool allowSynchronousMode,
|
||||
{
|
||||
// Choose a name using the PID and a process-unique ID.
|
||||
mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
|
||||
BufferQueue::setConsumerName(mName);
|
||||
|
||||
ST_LOGV("SurfaceTexture");
|
||||
if (bufferQueue == 0) {
|
||||
|
||||
ST_LOGV("Creating a new BufferQueue");
|
||||
mBufferQueue = new BufferQueue(allowSynchronousMode);
|
||||
}
|
||||
else {
|
||||
mBufferQueue = bufferQueue;
|
||||
}
|
||||
mBufferQueue->setConsumerName(mName);
|
||||
|
||||
memcpy(mCurrentTransformMatrix, mtxIdentity,
|
||||
sizeof(mCurrentTransformMatrix));
|
||||
}
|
||||
|
||||
SurfaceTexture::~SurfaceTexture() {
|
||||
ST_LOGV("~SurfaceTexture");
|
||||
|
||||
abandon();
|
||||
}
|
||||
|
||||
status_t SurfaceTexture::setBufferCountServer(int bufferCount) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return BufferQueue::setBufferCountServer(bufferCount);
|
||||
return mBufferQueue->setBufferCountServer(bufferCount);
|
||||
}
|
||||
|
||||
|
||||
status_t SurfaceTexture::setDefaultBufferSize(uint32_t w, uint32_t h)
|
||||
{
|
||||
return BufferQueue::setDefaultBufferSize(w, h);
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->setDefaultBufferSize(w, h);
|
||||
}
|
||||
|
||||
status_t SurfaceTexture::updateTexImage() {
|
||||
@ -154,11 +163,11 @@ status_t SurfaceTexture::updateTexImage() {
|
||||
return NO_INIT;
|
||||
}
|
||||
|
||||
BufferItem item;
|
||||
BufferQueue::BufferItem item;
|
||||
|
||||
// In asynchronous mode the list is guaranteed to be one buffer
|
||||
// deep, while in synchronous mode we use the oldest buffer.
|
||||
if (acquire(&item) == NO_ERROR) {
|
||||
if (mBufferQueue->acquire(&item) == NO_ERROR) {
|
||||
int buf = item.mBuf;
|
||||
// This buffer was newly allocated, so we need to clean up on our side
|
||||
if (item.mGraphicBuffer != NULL) {
|
||||
@ -205,19 +214,19 @@ status_t SurfaceTexture::updateTexImage() {
|
||||
failed = true;
|
||||
}
|
||||
if (failed) {
|
||||
releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
|
||||
mBufferQueue->releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
|
||||
mEGLSlots[buf].mFence);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (mCurrentTexture != INVALID_BUFFER_SLOT) {
|
||||
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
|
||||
if (mUseFenceSync) {
|
||||
EGLSyncKHR fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR,
|
||||
NULL);
|
||||
if (fence == EGL_NO_SYNC_KHR) {
|
||||
ALOGE("updateTexImage: error creating fence: %#x",
|
||||
eglGetError());
|
||||
releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
|
||||
mBufferQueue->releaseBuffer(buf, mEGLSlots[buf].mEglDisplay,
|
||||
mEGLSlots[buf].mFence);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -232,7 +241,7 @@ status_t SurfaceTexture::updateTexImage() {
|
||||
buf, item.mGraphicBuffer != NULL ? item.mGraphicBuffer->handle : 0);
|
||||
|
||||
// release old buffer
|
||||
releaseBuffer(mCurrentTexture,
|
||||
mBufferQueue->releaseBuffer(mCurrentTexture,
|
||||
mEGLSlots[mCurrentTexture].mEglDisplay,
|
||||
mEGLSlots[mCurrentTexture].mFence);
|
||||
|
||||
@ -385,7 +394,7 @@ void SurfaceTexture::setFrameAvailableListener(
|
||||
const sp<FrameAvailableListener>& listener) {
|
||||
ST_LOGV("setFrameAvailableListener");
|
||||
Mutex::Autolock lock(mMutex);
|
||||
BufferQueue::setFrameAvailableListener(listener);
|
||||
mBufferQueue->setFrameAvailableListener(listener);
|
||||
}
|
||||
|
||||
EGLImageKHR SurfaceTexture::createImage(EGLDisplay dpy,
|
||||
@ -426,7 +435,7 @@ uint32_t SurfaceTexture::getCurrentScalingMode() const {
|
||||
|
||||
bool SurfaceTexture::isSynchronousMode() const {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return BufferQueue::isSynchronousMode();
|
||||
return mBufferQueue->isSynchronousMode();
|
||||
}
|
||||
|
||||
void SurfaceTexture::abandon() {
|
||||
@ -435,7 +444,7 @@ void SurfaceTexture::abandon() {
|
||||
mCurrentTextureBuf.clear();
|
||||
|
||||
// destroy all egl buffers
|
||||
for (int i =0; i < NUM_BUFFER_SLOTS; i++) {
|
||||
for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
|
||||
mEGLSlots[i].mGraphicBuffer = 0;
|
||||
if (mEGLSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
|
||||
eglDestroyImageKHR(mEGLSlots[i].mEglDisplay,
|
||||
@ -446,13 +455,54 @@ void SurfaceTexture::abandon() {
|
||||
}
|
||||
|
||||
// disconnect from the BufferQueue
|
||||
BufferQueue::consumerDisconnect();
|
||||
mBufferQueue->consumerDisconnect();
|
||||
}
|
||||
|
||||
void SurfaceTexture::setName(const String8& name) {
|
||||
Mutex::Autolock _l(mMutex);
|
||||
mName = name;
|
||||
BufferQueue::setConsumerName(name);
|
||||
mBufferQueue->setConsumerName(name);
|
||||
}
|
||||
|
||||
status_t SurfaceTexture::setDefaultBufferFormat(uint32_t defaultFormat) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->setDefaultBufferFormat(defaultFormat);
|
||||
}
|
||||
|
||||
status_t SurfaceTexture::setConsumerUsageBits(uint32_t usage) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->setConsumerUsageBits(usage);
|
||||
}
|
||||
|
||||
status_t SurfaceTexture::setTransformHint(uint32_t hint) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->setTransformHint(hint);
|
||||
}
|
||||
|
||||
// Used for refactoring BufferQueue from SurfaceTexture
|
||||
// Should not be in final interface once users of SurfaceTexture are clean up.
|
||||
status_t SurfaceTexture::setSynchronousMode(bool enabled) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->setSynchronousMode(enabled);
|
||||
}
|
||||
|
||||
// Used for refactoring, should not be in final interface
|
||||
sp<BufferQueue> SurfaceTexture::getBufferQueue() const {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue;
|
||||
}
|
||||
|
||||
// Used for refactoring, should not be in final interface
|
||||
status_t SurfaceTexture::setBufferCount(int bufferCount) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->setBufferCount(bufferCount);
|
||||
}
|
||||
|
||||
// Used for refactoring, should not be in final interface
|
||||
status_t SurfaceTexture::connect(int api,
|
||||
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
|
||||
Mutex::Autolock lock(mMutex);
|
||||
return mBufferQueue->connect(api, outWidth, outHeight, outTransform);
|
||||
}
|
||||
|
||||
void SurfaceTexture::dump(String8& result) const
|
||||
@ -477,7 +527,7 @@ void SurfaceTexture::dump(String8& result, const char* prefix,
|
||||
result.append(buffer);
|
||||
|
||||
|
||||
BufferQueue::dump(result, prefix, buffer, SIZE);
|
||||
mBufferQueue->dump(result, prefix, buffer, SIZE);
|
||||
}
|
||||
|
||||
static void mtxMul(float out[16], const float a[16], const float b[16]) {
|
||||
|
@ -36,6 +36,14 @@ SurfaceTextureClient::SurfaceTextureClient(
|
||||
SurfaceTextureClient::setISurfaceTexture(surfaceTexture);
|
||||
}
|
||||
|
||||
// see SurfaceTextureClient.h
|
||||
SurfaceTextureClient::SurfaceTextureClient(const
|
||||
sp<SurfaceTexture>& surfaceTexture)
|
||||
{
|
||||
SurfaceTextureClient::init();
|
||||
SurfaceTextureClient::setISurfaceTexture(surfaceTexture->getBufferQueue());
|
||||
}
|
||||
|
||||
SurfaceTextureClient::SurfaceTextureClient() {
|
||||
SurfaceTextureClient::init();
|
||||
}
|
||||
|
@ -97,9 +97,19 @@ void Layer::onFirstRef()
|
||||
}
|
||||
}
|
||||
};
|
||||
mSurfaceTexture = new SurfaceTextureLayer(mTextureName, this);
|
||||
|
||||
// Creates a custom BufferQueue for SurfaceTexture to use
|
||||
sp<BufferQueue> bq = new SurfaceTextureLayer();
|
||||
mSurfaceTexture = new SurfaceTexture(mTextureName, true,
|
||||
GL_TEXTURE_EXTERNAL_OES, false,bq);
|
||||
|
||||
|
||||
|
||||
mSurfaceTexture->setTransformHint(getTransformHint());
|
||||
mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
|
||||
mSurfaceTexture->setFrameAvailableListener(new FrameQueuedListener(this));
|
||||
mSurfaceTexture->setSynchronousMode(true);
|
||||
|
||||
#ifdef USE_TRIPLE_BUFFERING
|
||||
#warning "using triple buffering"
|
||||
mSurfaceTexture->setBufferCountServer(3);
|
||||
@ -131,6 +141,14 @@ void Layer::setName(const String8& name) {
|
||||
mSurfaceTexture->setName(name);
|
||||
}
|
||||
|
||||
void Layer::validateVisibility(const Transform& globalTransform) {
|
||||
LayerBase::validateVisibility(globalTransform);
|
||||
|
||||
// This optimization allows the SurfaceTexture to bake in
|
||||
// the rotation so hardware overlays can be used
|
||||
mSurfaceTexture->setTransformHint(getTransformHint());
|
||||
}
|
||||
|
||||
sp<ISurface> Layer::createSurface()
|
||||
{
|
||||
class BSurface : public BnSurface, public LayerCleaner {
|
||||
@ -139,7 +157,7 @@ sp<ISurface> Layer::createSurface()
|
||||
sp<ISurfaceTexture> res;
|
||||
sp<const Layer> that( mOwner.promote() );
|
||||
if (that != NULL) {
|
||||
res = that->mSurfaceTexture;
|
||||
res = that->mSurfaceTexture->getBufferQueue();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -154,7 +172,7 @@ sp<ISurface> Layer::createSurface()
|
||||
|
||||
wp<IBinder> Layer::getSurfaceTextureBinder() const
|
||||
{
|
||||
return mSurfaceTexture->asBinder();
|
||||
return mSurfaceTexture->getBufferQueue()->asBinder();
|
||||
}
|
||||
|
||||
status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
||||
@ -193,6 +211,7 @@ status_t Layer::setBuffers( uint32_t w, uint32_t h,
|
||||
|
||||
mSurfaceTexture->setDefaultBufferSize(w, h);
|
||||
mSurfaceTexture->setDefaultBufferFormat(format);
|
||||
mSurfaceTexture->setConsumerUsageBits(getEffectiveUsage(0));
|
||||
|
||||
// we use the red index
|
||||
int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
|
||||
|
@ -77,6 +77,7 @@ public:
|
||||
virtual void onRemoved();
|
||||
virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
|
||||
virtual void setName(const String8& name);
|
||||
virtual void validateVisibility(const Transform& globalTransform);
|
||||
|
||||
// LayerBaseClient interface
|
||||
virtual wp<IBinder> getSurfaceTextureBinder() const;
|
||||
@ -105,7 +106,7 @@ private:
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
// constants
|
||||
sp<SurfaceTextureLayer> mSurfaceTexture;
|
||||
sp<SurfaceTexture> mSurfaceTexture;
|
||||
GLuint mTextureName;
|
||||
|
||||
// thread-safe
|
||||
|
@ -1399,6 +1399,7 @@ status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
|
||||
status_t err = NAME_NOT_FOUND;
|
||||
Mutex::Autolock _l(mStateLock);
|
||||
sp<LayerBaseClient> layer = client->getLayerUser(sid);
|
||||
|
||||
if (layer != 0) {
|
||||
err = purgatorizeLayer_l(layer);
|
||||
if (err == NO_ERROR) {
|
||||
|
@ -27,72 +27,18 @@ namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
SurfaceTextureLayer::SurfaceTextureLayer(GLuint tex, const sp<Layer>& layer)
|
||||
: SurfaceTexture(tex, true, GL_TEXTURE_EXTERNAL_OES, false), mLayer(layer) {
|
||||
SurfaceTextureLayer::SurfaceTextureLayer()
|
||||
: BufferQueue(true) {
|
||||
}
|
||||
|
||||
SurfaceTextureLayer::~SurfaceTextureLayer() {
|
||||
}
|
||||
|
||||
|
||||
status_t SurfaceTextureLayer::setDefaultBufferSize(uint32_t w, uint32_t h)
|
||||
{
|
||||
//ALOGD("%s, w=%u, h=%u", __PRETTY_FUNCTION__, w, h);
|
||||
return SurfaceTexture::setDefaultBufferSize(w, h);
|
||||
}
|
||||
|
||||
status_t SurfaceTextureLayer::setDefaultBufferFormat(uint32_t format)
|
||||
{
|
||||
mDefaultFormat = format;
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
status_t SurfaceTextureLayer::setBufferCount(int bufferCount) {
|
||||
status_t res = SurfaceTexture::setBufferCount(bufferCount);
|
||||
return res;
|
||||
}
|
||||
|
||||
status_t SurfaceTextureLayer::queueBuffer(int buf, int64_t timestamp,
|
||||
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
|
||||
|
||||
status_t res = SurfaceTexture::queueBuffer(buf, timestamp,
|
||||
outWidth, outHeight, outTransform);
|
||||
sp<Layer> layer(mLayer.promote());
|
||||
if (layer != NULL) {
|
||||
*outTransform = layer->getTransformHint();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
status_t SurfaceTextureLayer::dequeueBuffer(int *buf,
|
||||
uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
|
||||
|
||||
status_t res(NO_INIT);
|
||||
sp<Layer> layer(mLayer.promote());
|
||||
if (layer != NULL) {
|
||||
if (format == 0)
|
||||
format = mDefaultFormat;
|
||||
uint32_t effectiveUsage = layer->getEffectiveUsage(usage);
|
||||
//ALOGD("%s, w=%u, h=%u, format=%u, usage=%08x, effectiveUsage=%08x",
|
||||
// __PRETTY_FUNCTION__, w, h, format, usage, effectiveUsage);
|
||||
res = SurfaceTexture::dequeueBuffer(buf, w, h, format, effectiveUsage);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
status_t SurfaceTextureLayer::connect(int api,
|
||||
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform) {
|
||||
status_t err = SurfaceTexture::connect(api,
|
||||
status_t err = BufferQueue::connect(api,
|
||||
outWidth, outHeight, outTransform);
|
||||
if (err == NO_ERROR) {
|
||||
sp<Layer> layer(mLayer.promote());
|
||||
if (layer != NULL) {
|
||||
uint32_t orientation = layer->getOrientation();
|
||||
if (orientation & Transform::ROT_INVALID) {
|
||||
orientation = 0;
|
||||
}
|
||||
*outTransform = orientation;
|
||||
}
|
||||
switch(api) {
|
||||
case NATIVE_WINDOW_API_CPU:
|
||||
// SurfaceTextureClient supports only 2 buffers for CPU connections
|
||||
@ -110,7 +56,7 @@ status_t SurfaceTextureLayer::connect(int api,
|
||||
#endif
|
||||
// fall through to set synchronous mode when not defaulting to
|
||||
// async mode.
|
||||
deafult:
|
||||
default:
|
||||
err = setSynchronousMode(true);
|
||||
break;
|
||||
}
|
||||
|
@ -22,35 +22,21 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <utils/Errors.h>
|
||||
#include <gui/SurfaceTexture.h>
|
||||
#include <gui/BufferQueue.h>
|
||||
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class Layer;
|
||||
|
||||
class SurfaceTextureLayer : public SurfaceTexture
|
||||
// SurfaceTextureLayer is now a BufferQueue since SurfaceTexture has been
|
||||
// refactored
|
||||
class SurfaceTextureLayer : public BufferQueue
|
||||
{
|
||||
wp<Layer> mLayer;
|
||||
uint32_t mDefaultFormat;
|
||||
|
||||
public:
|
||||
SurfaceTextureLayer(GLuint tex, const sp<Layer>& layer);
|
||||
SurfaceTextureLayer();
|
||||
~SurfaceTextureLayer();
|
||||
|
||||
status_t setDefaultBufferSize(uint32_t w, uint32_t h);
|
||||
status_t setDefaultBufferFormat(uint32_t format);
|
||||
|
||||
public:
|
||||
virtual status_t setBufferCount(int bufferCount);
|
||||
|
||||
protected:
|
||||
virtual status_t queueBuffer(int buf, int64_t timestamp,
|
||||
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
|
||||
|
||||
virtual status_t dequeueBuffer(int *buf, uint32_t w, uint32_t h,
|
||||
uint32_t format, uint32_t usage);
|
||||
|
||||
virtual status_t connect(int api,
|
||||
uint32_t* outWidth, uint32_t* outHeight, uint32_t* outTransform);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user