Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 490aee0f authored by Jamie Gennis's avatar Jamie Gennis Committed by Android (Google) Code Review
Browse files

Merge "SurfaceTexture: inherit from ConsumerBase (try 2)" into jb-mr1-dev

parents 9b6a395e 9fea3421
Loading
Loading
Loading
Loading
+40 −37
Original line number Diff line number Diff line
@@ -86,42 +86,25 @@ private:

protected:

    // TODO: Fix this comment
    // ConsumerBase constructs a new ConsumerBase object. tex indicates the
    // name of the OpenGL ES texture to which images are to be streamed.
    // allowSynchronousMode specifies whether or not synchronous mode can be
    // 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. 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.
    //
    // For legacy reasons, the ConsumerBase is created in a state where it is
    // considered attached to an OpenGL ES context for the purposes of the
    // attachToContext and detachFromContext methods. However, despite being
    // considered "attached" to a context, the specific OpenGL ES context
    // doesn't get latched until the first call to updateTexImage. After that
    // point, all calls to updateTexImage must be made with the same OpenGL ES
    // context current.
    //
    // A ConsumerBase may be detached from one OpenGL ES context and then
    // attached to a different context using the detachFromContext and
    // attachToContext methods, respectively. The intention of these methods is
    // purely to allow a ConsumerBase to be transferred from one consumer
    // context to another. If such a transfer is not needed there is no
    // requirement that either of these methods be called.
    // ConsumerBase constructs a new ConsumerBase object to consume image
    // buffers from the given BufferQueue.
    ConsumerBase(const sp<BufferQueue> &bufferQueue);

    // Implementation of the BufferQueue::ConsumerListener interface.  These
    // calls are used to notify the ConsumerBase of asynchronous events in the
    // BufferQueue.
    // BufferQueue.  These methods should not need to be overridden by derived
    // classes, but if they are overridden the ConsumerBase implementation
    // must be called from the derived class.
    virtual void onFrameAvailable();
    virtual void onBuffersReleased();

    // freeBufferLocked frees up the given buffer slot.  If the slot has been
    // initialized this will release the reference to the GraphicBuffer in that
    // slot and destroy the EGLImage in that slot.  Otherwise it has no effect.
    // slot.  Otherwise it has no effect.
    //
    // Derived classes should override this method to clean up any state they
    // keep per slot.  If it is overridden, the derived class's implementation
    // must call ConsumerBase::freeBufferLocked.
    //
    // This method must be called with mMutex locked.
    virtual void freeBufferLocked(int slotIndex);
@@ -131,18 +114,43 @@ protected:
    // abandon method should be overridden by child classes to add abandon-
    // time behavior.
    //
    // Derived classes should override this method to clean up any object
    // state they keep (as opposed to per-slot state).  If it is overridden,
    // the derived class's implementation must call ConsumerBase::abandonLocked.
    //
    // This method must be called with mMutex locked.
    virtual void abandonLocked();

    // dumpLocked dumps the current state of the ConsumerBase object to the
    // result string.  Each line is prefixed with the string pointed to by the
    // prefix argument.  The buffer argument points to a buffer that may be
    // used for intermediate formatting data, and the size of that buffer is
    // indicated by the size argument.
    //
    // Derived classes should override this method to dump their internal
    // state.  If this method is overridden the derived class's implementation
    // should call ConsumerBase::dumpLocked.
    //
    // This method must be called with mMutex locked.
    virtual void dumpLocked(String8& result, const char* prefix, char* buffer,
            size_t SIZE) const;
            size_t size) const;

    // acquireBufferLocked fetches the next buffer from the BufferQueue and
    // updates the buffer slot for the buffer returned.
    //
    // Derived classes should override this method to perform any
    // initialization that must take place the first time a buffer is assigned
    // to a slot.  If it is overridden the derived class's implementation must
    // call ConsumerBase::acquireBufferLocked.
    virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item);

    // releaseBufferLocked relinquishes control over a buffer, returning that
    // control to the BufferQueue.
    //
    // Derived classes should override this method to perform any cleanup that
    // must take place when a buffer is released back to the BufferQueue.  If
    // it is overridden the derived class's implementation must call
    // ConsumerBase::acquireBufferLocked.
    virtual status_t releaseBufferLocked(int buf, EGLDisplay display,
           EGLSyncKHR eglFence, const sp<Fence>& fence);

@@ -189,17 +197,12 @@ protected:
    // if none is supplied
    sp<BufferQueue> mBufferQueue;

    // mAttached indicates whether the ConsumerBase is currently attached to
    // an OpenGL ES context.  For legacy reasons, this is initialized to true,
    // indicating that the ConsumerBase is considered to be attached to
    // whatever context is current at the time of the first updateTexImage call.
    // It is set to false by detachFromContext, and then set to true again by
    // attachToContext.
    bool mAttached;

    // mMutex is the mutex used to prevent concurrent access to the member
    // variables of ConsumerBase objects. It must be locked whenever the
    // member variables are accessed.
    // member variables are accessed or when any of the *Locked methods are
    // called.
    //
    // This mutex is intended to be locked by derived classes.
    mutable Mutex mMutex;
};

+29 −86
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include <gui/ISurfaceTexture.h>
#include <gui/BufferQueue.h>
#include <gui/ConsumerBase.h>

#include <ui/GraphicBuffer.h>

@@ -39,20 +40,9 @@ namespace android {

class String8;

class SurfaceTexture : public virtual RefBase,
        protected BufferQueue::ConsumerListener {
class SurfaceTexture : public ConsumerBase {
public:
    struct FrameAvailableListener : public virtual RefBase {
        // onFrameAvailable() is called each time an additional frame becomes
        // available for consumption. This means that frames that are queued
        // while in asynchronous mode only trigger the callback if no previous
        // frames are pending. Frames queued while in synchronous mode always
        // trigger the callback.
        //
        // This is called without any lock held and can be called concurrently
        // by multiple threads.
        virtual void onFrameAvailable() = 0;
    };
    typedef ConsumerBase::FrameAvailableListener FrameAvailableListener;

    // SurfaceTexture constructs a new SurfaceTexture object. tex indicates the
    // name of the OpenGL ES texture to which images are to be streamed.
@@ -82,8 +72,6 @@ public:
            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.
    //
@@ -132,16 +120,6 @@ public:
    // documented by the source.
    int64_t getTimestamp();

    // setFrameAvailableListener sets the listener object that will be notified
    // when a new frame becomes available.
    void setFrameAvailableListener(const sp<FrameAvailableListener>& listener);

    // getAllocator retrieves the binder object that must be referenced as long
    // as the GraphicBuffers dequeued from this SurfaceTexture are referenced.
    // Holding this binder reference prevents SurfaceFlinger from freeing the
    // buffers before the client is done with them.
    sp<IBinder> getAllocator();

    // setDefaultBufferSize is used to set the size of buffers returned by
    // requestBuffers when a with and height of zero is requested.
    // A call to setDefaultBufferSize() may trigger requestBuffers() to
@@ -180,17 +158,6 @@ public:
    // synchronous mode.
    bool isSynchronousMode() const;

    // abandon frees all the buffers and puts the SurfaceTexture into the
    // 'abandoned' state.  Once put in this state the SurfaceTexture can never
    // leave it.  When in the 'abandoned' state, all methods of the
    // ISurfaceTexture interface will fail with the NO_INIT error.
    //
    // Note that while calling this method causes all the buffers to be freed
    // from the perspective of the the SurfaceTexture, if there are additional
    // references on the buffers (e.g. if a buffer is referenced by a client or
    // by OpenGL ES as a texture) then those buffer will remain allocated.
    void abandon();

    // set the name of the SurfaceTexture that will be used to identify it in
    // log messages.
    void setName(const String8& name);
@@ -204,7 +171,9 @@ public:

    // getBufferQueue returns the BufferQueue object to which this
    // SurfaceTexture is connected.
    sp<BufferQueue> getBufferQueue() const;
    sp<BufferQueue> getBufferQueue() const {
        return mBufferQueue;
    }

    // detachFromContext detaches the SurfaceTexture from the calling thread's
    // current OpenGL ES context.  This context must be the same as the context
@@ -233,17 +202,25 @@ public:
    // current at the time of the last call to detachFromContext.
    status_t attachToContext(GLuint tex);

    // 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;

protected:

    // Implementation of the BufferQueue::ConsumerListener interface.  These
    // calls are used to notify the SurfaceTexture of asynchronous events in the
    // BufferQueue.
    virtual void onFrameAvailable();
    virtual void onBuffersReleased();
    // abandonLocked overrides the ConsumerBase method to clear
    // mCurrentTextureBuf in addition to the ConsumerBase behavior.
    virtual void abandonLocked();

    // dumpLocked overrides the ConsumerBase method to dump SurfaceTexture-
    // specific info in addition to the ConsumerBase behavior.
    virtual void dumpLocked(String8& result, const char* prefix, char* buffer,
           size_t size) const;

    // acquireBufferLocked overrides the ConsumerBase method to update the
    // mEglSlots array in addition to the ConsumerBase behavior.
    virtual status_t acquireBufferLocked(BufferQueue::BufferItem *item);

    // releaseBufferLocked overrides the ConsumerBase method to update the
    // mEglSlots array in addition to the ConsumerBase.
    virtual status_t releaseBufferLocked(int buf, EGLDisplay display,
           EGLSyncKHR eglFence, const sp<Fence>& fence);

    static bool isExternalFormat(uint32_t format);

@@ -271,7 +248,7 @@ private:
    // slot and destroy the EGLImage in that slot.  Otherwise it has no effect.
    //
    // This method must be called with mMutex locked.
    void freeBufferLocked(int slotIndex);
    virtual void freeBufferLocked(int slotIndex);

    // computeCurrentTransformMatrix computes the transform matrix for the
    // current texture.  It uses mCurrentTransform and the current GraphicBuffer
@@ -351,11 +328,9 @@ private:
    struct EGLSlot {
        EGLSlot()
        : mEglImage(EGL_NO_IMAGE_KHR),
          mFence(EGL_NO_SYNC_KHR) {
          mEglFence(EGL_NO_SYNC_KHR) {
        }

        sp<GraphicBuffer> mGraphicBuffer;

        // mEglImage is the EGLImage created from mGraphicBuffer.
        EGLImageKHR mEglImage;

@@ -363,14 +338,7 @@ private:
        // associated with this buffer slot may be dequeued. It is initialized
        // to EGL_NO_SYNC_KHR when the buffer is created and (optionally, based
        // on a compile-time option) set to a new sync object in updateTexImage.
        EGLSyncKHR mFence;

        // mReleaseFence is a fence which will signal when the buffer
        // associated with this buffer slot is no longer being used by the
        // consumer and can be overwritten. The buffer can be dequeued before
        // the fence signals; the producer is responsible for delaying writes
        // until it signals.
        sp<Fence> mReleaseFence;
        EGLSyncKHR mEglFence;
    };

    // mEglDisplay is the EGLDisplay with which this SurfaceTexture is currently
@@ -392,23 +360,7 @@ private:
    // slot that has not yet been used. The buffer allocated to a slot will also
    // be replaced if the requested buffer usage or geometry differs from that
    // of the buffer allocated to a slot.
    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.
    // It is initialized to false, and set to true in the abandon method.  A
    // BufferQueue that has been abandoned will return the NO_INIT error from
    // all ISurfaceTexture methods capable of returning an error.
    bool mAbandoned;

    // mName is a string used to identify the SurfaceTexture in log messages.
    // It can be set by the setName method.
    String8 mName;

    // mFrameAvailableListener is the listener object that will be called when a
    // new frame becomes available. If it is not NULL it will be called from
    // queueBuffer.
    sp<FrameAvailableListener> mFrameAvailableListener;
    EGLSlot mEglSlots[BufferQueue::NUM_BUFFER_SLOTS];

    // mCurrentTexture is the buffer slot index of the buffer that is currently
    // bound to the OpenGL texture. It is initialized to INVALID_BUFFER_SLOT,
@@ -418,22 +370,13 @@ 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;

    // mAttached indicates whether the SurfaceTexture is currently attached to
    // mAttached indicates whether the ConsumerBase is currently attached to
    // an OpenGL ES context.  For legacy reasons, this is initialized to true,
    // indicating that the SurfaceTexture is considered to be attached to
    // indicating that the ConsumerBase is considered to be attached to
    // whatever context is current at the time of the first updateTexImage call.
    // It is set to false by detachFromContext, and then set to true again by
    // attachToContext.
    bool mAttached;

    // mMutex is the mutex used to prevent concurrent access to the member
    // variables of SurfaceTexture objects. It must be locked whenever the
    // member variables are accessed.
    mutable Mutex mMutex;
};

// ----------------------------------------------------------------------------
+2 −1
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ static int32_t createProcessUniqueId() {
}

ConsumerBase::ConsumerBase(const sp<BufferQueue>& bufferQueue) :
        mAbandoned(false),
        mBufferQueue(bufferQueue) {
    // Choose a name using the PID and a process-unique ID.
    mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
+94 −193

File changed.

Preview size limit exceeded, changes collapsed.