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

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

Merge changes I9fb59763,I8b2c6e00

* changes:
  SurfaceTexture: consume buffers after err checks
  SurfaceTexture: change onFrameAvailable behavior
parents d11eccf3 9fb59763
Loading
Loading
Loading
Loading
+0 −7
Original line number Original line Diff line number Diff line
@@ -233,12 +233,6 @@ static jlong SurfaceTexture_getTimestamp(JNIEnv* env, jobject thiz)
    return surfaceTexture->getTimestamp();
    return surfaceTexture->getTimestamp();
}
}


static jint SurfaceTexture_getQueuedCount(JNIEnv* env, jobject thiz)
{
    sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz));
    return surfaceTexture->getQueuedCount();
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


static JNINativeMethod gSurfaceTextureMethods[] = {
static JNINativeMethod gSurfaceTextureMethods[] = {
@@ -249,7 +243,6 @@ static JNINativeMethod gSurfaceTextureMethods[] = {
    {"nativeUpdateTexImage",     "()V",   (void*)SurfaceTexture_updateTexImage },
    {"nativeUpdateTexImage",     "()V",   (void*)SurfaceTexture_updateTexImage },
    {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
    {"nativeGetTransformMatrix", "([F)V", (void*)SurfaceTexture_getTransformMatrix },
    {"nativeGetTimestamp",       "()J",   (void*)SurfaceTexture_getTimestamp },
    {"nativeGetTimestamp",       "()J",   (void*)SurfaceTexture_getTimestamp },
    {"nativeGetQueuedCount",     "()I",   (void*)SurfaceTexture_getQueuedCount }
};
};


int register_android_graphics_SurfaceTexture(JNIEnv* env)
int register_android_graphics_SurfaceTexture(JNIEnv* env)
+0 −4
Original line number Original line Diff line number Diff line
@@ -144,10 +144,6 @@ public class SurfaceTexture {
     */
     */
    public void updateTexImage() {
    public void updateTexImage() {
        nativeUpdateTexImage();
        nativeUpdateTexImage();
        if (nativeGetQueuedCount() > 0) {
            Message m = mEventHandler.obtainMessage();
            mEventHandler.sendMessage(m);
        }
    }
    }


    /**
    /**
+8 −10
Original line number Original line Diff line number Diff line
@@ -46,11 +46,14 @@ public:
    enum { NUM_BUFFER_SLOTS = 32 };
    enum { NUM_BUFFER_SLOTS = 32 };


    struct FrameAvailableListener : public virtual RefBase {
    struct FrameAvailableListener : public virtual RefBase {
        // onFrameAvailable() is called from queueBuffer() is the FIFO is
        // onFrameAvailable() is called from queueBuffer() each time an
        // empty. You can use SurfaceTexture::getQueuedCount() to
        // additional frame becomes available for consumption. This means that
        // figure out if there are more frames waiting.
        // frames that are queued while in asynchronous mode only trigger the
        // This is called without any lock held can be called concurrently by
        // callback if no previous frames are pending. Frames queued while in
        // multiple threads.
        // 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;
        virtual void onFrameAvailable() = 0;
    };
    };


@@ -101,11 +104,6 @@ public:
    // target texture belongs is bound to the calling thread.
    // target texture belongs is bound to the calling thread.
    status_t updateTexImage();
    status_t updateTexImage();


    // getqueuedCount returns the number of queued frames waiting in the
    // FIFO. In asynchronous mode, this always returns 0 or 1 since
    // frames are not accumulating in the FIFO.
    size_t getQueuedCount() const;

    // setBufferCountServer set the buffer count. If the client has requested
    // setBufferCountServer set the buffer count. If the client has requested
    // a buffer count using setBufferCount, the server-buffer count will
    // a buffer count using setBufferCount, the server-buffer count will
    // take effect once the client sets the count back to zero.
    // take effect once the client sets the count back to zero.
+20 −25
Original line number Original line Diff line number Diff line
@@ -417,17 +417,22 @@ status_t SurfaceTexture::queueBuffer(int buf, int64_t timestamp) {
            return -EINVAL;
            return -EINVAL;
        }
        }


        if (mQueue.empty()) {
            listener = mFrameAvailableListener;
        }

        if (mSynchronousMode) {
        if (mSynchronousMode) {
            // in synchronous mode we queue all buffers in a FIFO
            // In synchronous mode we queue all buffers in a FIFO.
            mQueue.push_back(buf);
            mQueue.push_back(buf);

            // Synchronous mode always signals that an additional frame should
            // be consumed.
            listener = mFrameAvailableListener;
        } else {
        } else {
            // in asynchronous mode we only keep the most recent buffer
            // In asynchronous mode we only keep the most recent buffer.
            if (mQueue.empty()) {
            if (mQueue.empty()) {
                mQueue.push_back(buf);
                mQueue.push_back(buf);

                // Asynchronous mode only signals that a frame should be
                // consumed if no previous frame was pending. If a frame were
                // pending then the consumer would have already been notified.
                listener = mFrameAvailableListener;
            } else {
            } else {
                Fifo::iterator front(mQueue.begin());
                Fifo::iterator front(mQueue.begin());
                // buffer currently queued is freed
                // buffer currently queued is freed
@@ -483,24 +488,14 @@ status_t SurfaceTexture::setTransform(uint32_t transform) {


status_t SurfaceTexture::updateTexImage() {
status_t SurfaceTexture::updateTexImage() {
    LOGV("SurfaceTexture::updateTexImage");
    LOGV("SurfaceTexture::updateTexImage");

    Mutex::Autolock lock(mMutex);
    Mutex::Autolock lock(mMutex);


    int buf = mCurrentTexture;
    // In asynchronous mode the list is guaranteed to be one buffer
    // deep, while in synchronous mode we use the oldest buffer.
    if (!mQueue.empty()) {
    if (!mQueue.empty()) {
        // in asynchronous mode the list is guaranteed to be one buffer deep,
        // while in synchronous mode we use the oldest buffer
        Fifo::iterator front(mQueue.begin());
        Fifo::iterator front(mQueue.begin());
        buf = *front;
        int buf = *front;
        mQueue.erase(front);
        if (mQueue.isEmpty()) {
            mDequeueCondition.signal();
        }
    }


    // Initially both mCurrentTexture and buf are INVALID_BUFFER_SLOT,
    // so this check will fail until a buffer gets queued.
    if (mCurrentTexture != buf) {
        // Update the GL texture object.
        // Update the GL texture object.
        EGLImageKHR image = mSlots[buf].mEglImage;
        EGLImageKHR image = mSlots[buf].mEglImage;
        if (image == EGL_NO_IMAGE_KHR) {
        if (image == EGL_NO_IMAGE_KHR) {
@@ -538,7 +533,7 @@ status_t SurfaceTexture::updateTexImage() {
        }
        }


        if (mCurrentTexture != INVALID_BUFFER_SLOT) {
        if (mCurrentTexture != INVALID_BUFFER_SLOT) {
            // the current buffer becomes FREE if it was still in the queued
            // The current buffer becomes FREE if it was still in the queued
            // state. If it has already been given to the client
            // state. If it has already been given to the client
            // (synchronous mode), then it stays in DEQUEUED state.
            // (synchronous mode), then it stays in DEQUEUED state.
            if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED)
            if (mSlots[mCurrentTexture].mBufferState == BufferSlot::QUEUED)
@@ -553,17 +548,17 @@ status_t SurfaceTexture::updateTexImage() {
        mCurrentTransform = mSlots[buf].mTransform;
        mCurrentTransform = mSlots[buf].mTransform;
        mCurrentTimestamp = mSlots[buf].mTimestamp;
        mCurrentTimestamp = mSlots[buf].mTimestamp;
        computeCurrentTransformMatrix();
        computeCurrentTransformMatrix();

        // Now that we've passed the point at which failures can happen,
        // it's safe to remove the buffer from the front of the queue.
        mQueue.erase(front);
        mDequeueCondition.signal();
        mDequeueCondition.signal();
    } else {
    } else {
        // We always bind the texture even if we don't update its contents.
        // We always bind the texture even if we don't update its contents.
        glBindTexture(mCurrentTextureTarget, mTexName);
        glBindTexture(mCurrentTextureTarget, mTexName);
    }
    }
    return OK;
}


size_t SurfaceTexture::getQueuedCount() const {
    return OK;
    Mutex::Autolock lock(mMutex);
    return mQueue.size();
}
}


bool SurfaceTexture::isExternalFormat(uint32_t format)
bool SurfaceTexture::isExternalFormat(uint32_t format)
+8 −11
Original line number Original line Diff line number Diff line
@@ -101,10 +101,9 @@ Layer::~Layer()
}
}


void Layer::onFrameQueued() {
void Layer::onFrameQueued() {
    if (android_atomic_or(1, &mQueuedFrames) == 0) {
    android_atomic_inc(&mQueuedFrames);
    mFlinger->signalEvent();
    mFlinger->signalEvent();
}
}
}


// called with SurfaceFlinger::mStateLock as soon as the layer is entered
// called with SurfaceFlinger::mStateLock as soon as the layer is entered
// in the purgatory list
// in the purgatory list
@@ -406,20 +405,18 @@ bool Layer::isCropped() const {


void Layer::lockPageFlip(bool& recomputeVisibleRegions)
void Layer::lockPageFlip(bool& recomputeVisibleRegions)
{
{
    if (android_atomic_and(0, &mQueuedFrames)) {
    if (mQueuedFrames > 0) {
        // signal another event if we have more frames pending
        if (android_atomic_dec(&mQueuedFrames) > 1) {
            mFlinger->signalEvent();
        }

        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
        if (mSurfaceTexture->updateTexImage() < NO_ERROR) {
            // something happened!
            // something happened!
            recomputeVisibleRegions = true;
            recomputeVisibleRegions = true;
            return;
            return;
        }
        }


        // signal another event if we have more frames waiting
        if (mSurfaceTexture->getQueuedCount()) {
            if (android_atomic_or(1, &mQueuedFrames) == 0) {
                mFlinger->signalEvent();
            }
        }

        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
        mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
        mSurfaceTexture->getTransformMatrix(mTextureMatrix);
        mSurfaceTexture->getTransformMatrix(mTextureMatrix);