diff options
Diffstat (limited to 'services/surfaceflinger/BufferLayerConsumer.cpp')
-rw-r--r-- | services/surfaceflinger/BufferLayerConsumer.cpp | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 96b22478ab..8722952bba 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -25,7 +25,7 @@ #include "BufferLayerConsumer.h" #include "Layer.h" -#include "Scheduler/VsyncController.h" +#include "Scheduler/DispSync.h" #include <inttypes.h> @@ -40,6 +40,7 @@ #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> #include <private/gui/ComposerService.h> +#include <renderengine/Image.h> #include <renderengine/RenderEngine.h> #include <utils/Log.h> #include <utils/String8.h> @@ -152,9 +153,25 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, nsecs_t e if (err != NO_ERROR) { return err; } + + 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(); + } + return err; } +status_t BufferLayerConsumer::bindTextureImage() { + Mutex::Autolock lock(mMutex); + return bindTextureImageLocked(); +} + void BufferLayerConsumer::setReleaseFence(const sp<Fence>& fence) { if (!fence->isValid()) { return; @@ -166,7 +183,7 @@ void BufferLayerConsumer::setReleaseFence(const sp<Fence>& fence) { } auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer - : mCurrentTextureBuffer->getBuffer(); + : mCurrentTextureBuffer->graphicBuffer(); auto err = addReleaseFence(slot, buffer, fence); if (err != OK) { BLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", strerror(-err), err); @@ -205,11 +222,9 @@ status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t pres // before, so we need to clean up old references. if (item->mGraphicBuffer != nullptr) { std::lock_guard<std::mutex> lock(mImagesMutex); - if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->getBuffer() == nullptr || - mImages[item->mSlot]->getBuffer()->getId() != item->mGraphicBuffer->getId()) { - mImages[item->mSlot] = std::make_shared< - renderengine::ExternalTexture>(item->mGraphicBuffer, mRE, - renderengine::ExternalTexture::Usage::READABLE); + if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->graphicBuffer() == nullptr || + mImages[item->mSlot]->graphicBuffer()->getId() != item->mGraphicBuffer->getId()) { + mImages[item->mSlot] = std::make_shared<Image>(item->mGraphicBuffer, mRE); } } @@ -223,8 +238,8 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, int slot = item.mSlot; BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, - (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->getBuffer() != nullptr) - ? mCurrentTextureBuffer->getBuffer()->handle + (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->graphicBuffer() != nullptr) + ? mCurrentTextureBuffer->graphicBuffer()->handle : 0, slot, mSlots[slot].mGraphicBuffer->handle); @@ -232,7 +247,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, // releaseBufferLocked() if we're in shared buffer mode and both buffers are // the same. - std::shared_ptr<renderengine::ExternalTexture> nextTextureBuffer; + std::shared_ptr<Image> nextTextureBuffer; { std::lock_guard<std::mutex> lock(mImagesMutex); nextTextureBuffer = mImages[slot]; @@ -242,7 +257,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { status_t status = - releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->getBuffer()); + releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->graphicBuffer()); if (status < NO_ERROR) { BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); @@ -251,7 +266,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } } else { pendingRelease->currentTexture = mCurrentTexture; - pendingRelease->graphicBuffer = mCurrentTextureBuffer->getBuffer(); + pendingRelease->graphicBuffer = mCurrentTextureBuffer->graphicBuffer(); pendingRelease->isPending = true; } } @@ -277,6 +292,17 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, return err; } +status_t BufferLayerConsumer::bindTextureImageLocked() { + ATRACE_CALL(); + + if (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->graphicBuffer() != nullptr) { + return mRE.bindExternalTextureBuffer(mTexName, mCurrentTextureBuffer->graphicBuffer(), + mCurrentFence); + } + + return NO_INIT; +} + void BufferLayerConsumer::getTransformMatrix(float mtx[16]) { Mutex::Autolock lock(mMutex); memcpy(mtx, mCurrentTransformMatrix, sizeof(mCurrentTransformMatrix)); @@ -302,14 +328,14 @@ void BufferLayerConsumer::setFilteringEnabled(bool enabled) { void BufferLayerConsumer::computeCurrentTransformMatrixLocked() { BLC_LOGV("computeCurrentTransformMatrixLocked"); - if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->getBuffer() == nullptr) { + if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->graphicBuffer() == nullptr) { BLC_LOGD("computeCurrentTransformMatrixLocked: " "mCurrentTextureBuffer is nullptr"); } GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, mCurrentTextureBuffer == nullptr ? nullptr - : mCurrentTextureBuffer->getBuffer(), + : mCurrentTextureBuffer->graphicBuffer(), getCurrentCropLocked(), mCurrentTransform, mFilteringEnabled); } @@ -361,8 +387,7 @@ int BufferLayerConsumer::getCurrentApi() const { return mCurrentApi; } -std::shared_ptr<renderengine::ExternalTexture> BufferLayerConsumer::getCurrentBuffer( - int* outSlot, sp<Fence>* outFence) const { +sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot, sp<Fence>* outFence) const { Mutex::Autolock lock(mMutex); if (outSlot != nullptr) { @@ -373,7 +398,7 @@ std::shared_ptr<renderengine::ExternalTexture> BufferLayerConsumer::getCurrentBu *outFence = mCurrentFence; } - return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer; + return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer->graphicBuffer(); } Rect BufferLayerConsumer::getCurrentCrop() const { @@ -458,12 +483,10 @@ void BufferLayerConsumer::onSidebandStreamChanged() { void BufferLayerConsumer::onBufferAvailable(const BufferItem& item) { if (item.mGraphicBuffer != nullptr && item.mSlot != BufferQueue::INVALID_BUFFER_SLOT) { std::lock_guard<std::mutex> lock(mImagesMutex); - const std::shared_ptr<renderengine::ExternalTexture>& oldImage = mImages[item.mSlot]; - if (oldImage == nullptr || oldImage->getBuffer() == nullptr || - oldImage->getBuffer()->getId() != item.mGraphicBuffer->getId()) { - mImages[item.mSlot] = std::make_shared< - renderengine::ExternalTexture>(item.mGraphicBuffer, mRE, - renderengine::ExternalTexture::Usage::READABLE); + const std::shared_ptr<Image>& oldImage = mImages[item.mSlot]; + if (oldImage == nullptr || oldImage->graphicBuffer() == nullptr || + oldImage->graphicBuffer()->getId() != item.mGraphicBuffer->getId()) { + mImages[item.mSlot] = std::make_shared<Image>(item.mGraphicBuffer, mRE); } } } @@ -503,6 +526,19 @@ void BufferLayerConsumer::dumpLocked(String8& result, const char* prefix) const ConsumerBase::dumpLocked(result, prefix); } + +BufferLayerConsumer::Image::Image(const sp<GraphicBuffer>& graphicBuffer, + renderengine::RenderEngine& engine) + : mGraphicBuffer(graphicBuffer), mRE(engine) { + mRE.cacheExternalTextureBuffer(mGraphicBuffer); +} + +BufferLayerConsumer::Image::~Image() { + if (mGraphicBuffer != nullptr) { + ALOGV("Destroying buffer: %" PRId64, mGraphicBuffer->getId()); + mRE.unbindExternalTextureBuffer(mGraphicBuffer->getId()); + } +} }; // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues |