// updateTexImage acquires the most recently queued buffer, and sets the
// image contents of the target texture to it.
//
// This call may only be made while RenderEngine is current.
//
// This calls doFenceWait to ensure proper synchronization unless native
// fence is supported.
//
// Unlike the GLConsumer version, this version takes a functor that may be
// used to reject the newly acquired buffer.  It also does not bind the
// RenderEngine texture until bindTextureImage is called.
status_t updateTexImage(BufferRejecter* rejecter, nsecs_t expectedPresentTime,
                        bool* autoRefresh, bool* queuedBuffer, uint64_t maxFrameNumber);

updateTexImage() 请求最后一个入队的 buffer。注释没看懂,直接看实现。

BufferItem item;

// Acquire the next buffer.
// In asynchronous mode the list is guaranteed to be one buffer
// deep, while in synchronous mode we use the oldest buffer.
status_t err = acquireBufferLocked(&item, expectedPresentTime, maxFrameNumber);
if (err != NO_ERROR) {
    if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
        err = NO_ERROR;
    } else if (err == BufferQueue::PRESENT_LATER) {
        // return the error, without logging
    } else {
        BLC_LOGE("updateTexImage: acquire failed: %s (%d)", strerror(-err), err);
    }
    return err;
}

调用 BufferLayerConsumer::acquireBufferLocked() 获取 buffer。如果 BufferItem::mGraphicBuffer 不是空,则更新 BufferLayerConsumer::Image 数组。

如果返回 NO_BUFFER_AVAILABLE,则返回 NO_ERROR。如果返回 PRESENT_LATER 则直接返回,说明要延迟显示。

// We call the rejecter here, in case the caller has a reason to
// not accept this buffer.  This is used by SurfaceFlinger to
// reject buffers which have the wrong size
int slot = item.mSlot;
if (rejecter && rejecter->reject(mSlots[slot].mGraphicBuffer, item)) {
    releaseBufferLocked(slot, mSlots[slot].mGraphicBuffer);
    return BUFFER_REJECTED;
}

reject() 对宽高的执行复杂的检查,具体实现不看了。如果要拒绝则调用 ConsumerBase::releaseBufferLocked() 释放引用,并返回 BUFFER_REJECTED

// Release the previous buffer.
err = updateAndReleaseLocked(item, &mPendingRelease);
if (err != NO_ERROR) {
    return err;
}

如果没有拒绝,则调用 BufferLayerConsumer::updateAndReleaseLocked() 释放上一个 buffer 并更新成员,其中有 mCurrentTextureBuffer,它是 BufferLayerConsumer::Image 类型,会在绑定 texture 时使用。

if (!mRE.useNativeFenceSync()) {
    // Bind the new buffer to the GL texture.
    //
    // Older devices require the "implicit" synchronization provided
    // by glEGLImageTargetTexture2DOES, which this method calls.  Newer
    // devices will either call this in Layer::onDraw, or (if it's not
    // a GL-composited layer) not at all.
    err = bindTextureImageLocked();
}

最后,根据 RenderEngine 状态调用 BufferLayerConsumer::bindTextureImageLocked() 绑定 texture。