Loading services/surfaceflinger/BufferLayer.h +1 −1 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ private: virtual void setFilteringEnabled(bool enabled) = 0; virtual status_t bindTextureImage() const = 0; virtual status_t bindTextureImage() = 0; virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, const sp<Fence>& flushFence) = 0; Loading services/surfaceflinger/BufferLayerConsumer.cpp +53 −68 Original line number Diff line number Diff line Loading @@ -111,12 +111,6 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, nsecs_t e return NO_INIT; } // Make sure RenderEngine is current if (!mRE.isCurrent()) { BLC_LOGE("updateTexImage: RenderEngine is not current"); return INVALID_OPERATION; } BufferItem item; // Acquire the next buffer. Loading Loading @@ -185,8 +179,7 @@ void BufferLayerConsumer::setReleaseFence(const sp<Fence>& fence) { return; } auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer : mCurrentTextureImage->graphicBuffer(); auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer : mCurrentTextureBuffer; auto err = addReleaseFence(slot, buffer, fence); if (err != OK) { BLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", strerror(-err), err); Loading Loading @@ -222,10 +215,9 @@ status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t pres } // If item->mGraphicBuffer is not null, this buffer has not been acquired // before, so any prior EglImage created is using a stale buffer. This // replaces any old EglImage with a new one (using the new buffer). // before. if (item->mGraphicBuffer != nullptr) { mImages[item->mSlot] = new Image(item->mGraphicBuffer, mRE); mImages[item->mSlot] = nullptr; } return NO_ERROR; Loading @@ -252,19 +244,18 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, mCurrentTextureImage != nullptr ? mCurrentTextureImage->graphicBufferHandle() : 0, slot, mSlots[slot].mGraphicBuffer->handle); mCurrentTextureBuffer != nullptr ? mCurrentTextureBuffer->handle : 0, slot, mSlots[slot].mGraphicBuffer->handle); // Hang onto the pointer so that it isn't freed in the call to // releaseBufferLocked() if we're in shared buffer mode and both buffers are // the same. sp<Image> nextTextureImage = mImages[slot]; sp<GraphicBuffer> nextTextureBuffer = mSlots[slot].mGraphicBuffer; // release old buffer if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { status_t status = releaseBufferLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer()); status_t status = releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer); if (status < NO_ERROR) { BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); Loading @@ -273,14 +264,15 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } } else { pendingRelease->currentTexture = mCurrentTexture; pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); pendingRelease->graphicBuffer = mCurrentTextureBuffer; pendingRelease->isPending = true; } } // Update the BufferLayerConsumer state. mCurrentTexture = slot; mCurrentTextureImage = nextTextureImage; mCurrentTextureBuffer = nextTextureBuffer; mCurrentTextureImageFreed = nullptr; mCurrentCrop = item.mCrop; mCurrentTransform = item.mTransform; mCurrentScalingMode = item.mScalingMode; Loading @@ -301,22 +293,46 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, status_t BufferLayerConsumer::bindTextureImageLocked() { ATRACE_CALL(); mRE.checkErrors(); if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) { // It is possible for the current slot's buffer to be freed before a new one // is bound. In that scenario we still want to bind the image. if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureBuffer == nullptr) { BLC_LOGE("bindTextureImage: no currently-bound texture"); mRE.bindExternalTextureImage(mTexName, *mRE.createImage()); return NO_INIT; } status_t err = mCurrentTextureImage->createIfNeeded(); if (err != NO_ERROR) { renderengine::Image* imageToRender; // mCurrentTextureImageFreed is non-null iff mCurrentTexture == // BufferQueue::INVALID_BUFFER_SLOT, so we can omit that check. if (mCurrentTextureImageFreed) { imageToRender = mCurrentTextureImageFreed.get(); } else if (mImages[mCurrentTexture]) { imageToRender = mImages[mCurrentTexture].get(); } else { std::unique_ptr<renderengine::Image> image = mRE.createImage(); bool success = image->setNativeWindowBuffer(mCurrentTextureBuffer->getNativeBuffer(), mCurrentTextureBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); if (!success) { BLC_LOGE("bindTextureImage: Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d", mCurrentTextureBuffer->getWidth(), mCurrentTextureBuffer->getHeight(), mCurrentTextureBuffer->getStride(), mCurrentTextureBuffer->getUsage(), mCurrentTextureBuffer->getPixelFormat()); BLC_LOGW("bindTextureImage: can't create image on slot=%d", mCurrentTexture); mRE.bindExternalTextureImage(mTexName, *mRE.createImage()); mRE.bindExternalTextureImage(mTexName, *image); return UNKNOWN_ERROR; } imageToRender = image.get(); // Cache the image here so that we can reuse it. mImages[mCurrentTexture] = std::move(image); } mRE.bindExternalTextureImage(mTexName, mCurrentTextureImage->image()); mRE.bindExternalTextureImage(mTexName, *imageToRender); // Wait for the new buffer to be ready. return doFenceWaitLocked(); Loading @@ -333,8 +349,7 @@ status_t BufferLayerConsumer::syncForReleaseLocked(const sp<Fence>& releaseFence return UNKNOWN_ERROR; } status_t err = addReleaseFenceLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer(), releaseFence); addReleaseFenceLocked(mCurrentTexture, mCurrentTextureBuffer, releaseFence); if (err != OK) { BLC_LOGE("syncForReleaseLocked: error adding release fence: " "%s (%d)", Loading @@ -361,24 +376,22 @@ void BufferLayerConsumer::setFilteringEnabled(bool enabled) { bool needsRecompute = mFilteringEnabled != enabled; mFilteringEnabled = enabled; if (needsRecompute && mCurrentTextureImage == nullptr) { BLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == nullptr"); if (needsRecompute && mCurrentTextureBuffer == nullptr) { BLC_LOGD("setFilteringEnabled called with mCurrentTextureBuffer == nullptr"); } if (needsRecompute && mCurrentTextureImage != nullptr) { if (needsRecompute && mCurrentTextureBuffer != nullptr) { computeCurrentTransformMatrixLocked(); } } void BufferLayerConsumer::computeCurrentTransformMatrixLocked() { BLC_LOGV("computeCurrentTransformMatrixLocked"); sp<GraphicBuffer> buf = (mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer(); if (buf == nullptr) { if (mCurrentTextureBuffer == nullptr) { BLC_LOGD("computeCurrentTransformMatrixLocked: " "mCurrentTextureImage is nullptr"); "mCurrentTextureBuffer is nullptr"); } GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, buf, mCurrentCrop, GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, mCurrentTextureBuffer, mCurrentCrop, mCurrentTransform, mFilteringEnabled); } Loading Loading @@ -427,7 +440,7 @@ sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot) const { *outSlot = mCurrentTexture; } return (mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer(); return mCurrentTextureBuffer; } Rect BufferLayerConsumer::getCurrentCrop() const { Loading Loading @@ -458,11 +471,6 @@ std::shared_ptr<FenceTime> BufferLayerConsumer::getCurrentFenceTime() const { } status_t BufferLayerConsumer::doFenceWaitLocked() const { if (!mRE.isCurrent()) { BLC_LOGE("doFenceWait: RenderEngine is not current"); return INVALID_OPERATION; } if (mCurrentFence->isValid()) { if (mRE.useWaitSync()) { base::unique_fd fenceFd(mCurrentFence->dup()); Loading Loading @@ -490,8 +498,10 @@ void BufferLayerConsumer::freeBufferLocked(int slotIndex) { BLC_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); if (slotIndex == mCurrentTexture) { mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; mCurrentTextureImageFreed = std::move(mImages[slotIndex]); } else { mImages[slotIndex] = nullptr; } mImages[slotIndex].clear(); ConsumerBase::freeBufferLocked(slotIndex); } Loading Loading @@ -530,7 +540,7 @@ void BufferLayerConsumer::addAndGetFrameTimestamps(const NewFrameEventsEntry* ne void BufferLayerConsumer::abandonLocked() { BLC_LOGV("abandonLocked"); mCurrentTextureImage.clear(); mCurrentTextureBuffer.clear(); ConsumerBase::abandonLocked(); } Loading @@ -548,29 +558,4 @@ void BufferLayerConsumer::dumpLocked(String8& result, const char* prefix) const ConsumerBase::dumpLocked(result, prefix); } BufferLayerConsumer::Image::Image(sp<GraphicBuffer> graphicBuffer, renderengine::RenderEngine& engine) : mGraphicBuffer(graphicBuffer), mImage{engine.createImage()}, mCreated(false), mCropWidth(0), mCropHeight(0) {} BufferLayerConsumer::Image::~Image() = default; status_t BufferLayerConsumer::Image::createIfNeeded() { if (mCreated) return OK; mCreated = mImage->setNativeWindowBuffer(mGraphicBuffer->getNativeBuffer(), mGraphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); if (!mCreated) { const sp<GraphicBuffer>& buffer = mGraphicBuffer; ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d", buffer->getWidth(), buffer->getHeight(), buffer->getStride(), buffer->getUsage(), buffer->getPixelFormat()); } return mCreated ? OK : UNKNOWN_ERROR; } }; // namespace android services/surfaceflinger/BufferLayerConsumer.h +17 −55 Original line number Diff line number Diff line Loading @@ -185,8 +185,7 @@ protected: // specific info in addition to the ConsumerBase behavior. virtual void dumpLocked(String8& result, const char* prefix) const; // acquireBufferLocked overrides the ConsumerBase method to update the // mImages array in addition to the ConsumerBase behavior. // See ConsumerBase::acquireBufferLocked virtual status_t acquireBufferLocked(BufferItem* item, nsecs_t presentWhen, uint64_t maxFrameNumber = 0) override; Loading @@ -210,53 +209,14 @@ protected: PendingRelease* pendingRelease = nullptr, const sp<Fence>& releaseFence = Fence::NO_FENCE); // Binds mTexName and the current buffer to TEXTURE_EXTERNAL target. Uses // mCurrentTexture if it's set, mCurrentTextureImage if not. If the // bind succeeds, this calls doFenceWait. // Binds mTexName and the current buffer to TEXTURE_EXTERNAL target. // If the bind succeeds, this calls doFenceWait. status_t bindTextureImageLocked(); private: // Image is a utility class for tracking and creating renderengine::Images. There // is primarily just one image per slot, but there is also special cases: // - After freeBuffer, we must still keep the current image/buffer // Reference counting renderengine::Images lets us handle all these cases easily while // also only creating new renderengine::Images from buffers when required. class Image : public LightRefBase<Image> { public: Image(sp<GraphicBuffer> graphicBuffer, renderengine::RenderEngine& engine); Image(const Image& rhs) = delete; Image& operator=(const Image& rhs) = delete; // createIfNeeded creates an renderengine::Image if we haven't created one yet. status_t createIfNeeded(); const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; } const native_handle* graphicBufferHandle() { return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle; } const renderengine::Image& image() const { return *mImage; } private: // Only allow instantiation using ref counting. friend class LightRefBase<Image>; virtual ~Image(); // mGraphicBuffer is the buffer that was used to create this image. sp<GraphicBuffer> mGraphicBuffer; // mImage is the image created from mGraphicBuffer. std::unique_ptr<renderengine::Image> mImage; bool mCreated; int32_t mCropWidth; int32_t mCropHeight; }; // 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 renderengine::Image in that slot. Otherwise it has no // effect. // that slot. Otherwise it has no effect. // // This method must be called with mMutex locked. virtual void freeBufferLocked(int slotIndex); Loading Loading @@ -290,10 +250,10 @@ private: // consume buffers as hardware textures. static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; // mCurrentTextureImage is the Image/buffer of the current texture. It's // mCurrentTextureImage is the buffer containing the current texture. It's // possible that this buffer is not associated with any buffer slot, so we // must track it separately in order to support the getCurrentBuffer method. sp<Image> mCurrentTextureImage; sp<GraphicBuffer> mCurrentTextureBuffer; // mCurrentCrop is the crop rectangle that applies to the current texture. // It gets set each time updateTexImage is called. Loading Loading @@ -363,15 +323,6 @@ private: wp<ContentsChangedListener> mContentsChangedListener; // mImages stores the buffers that have been allocated by the BufferQueue // for each buffer slot. It is initialized to null pointers, and gets // filled in with the result of BufferQueue::acquire when the // client dequeues a buffer from a // 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. sp<Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS]; // mCurrentTexture is the buffer slot index of the buffer that is currently // bound to the RenderEngine texture. It is initialized to INVALID_BUFFER_SLOT, // indicating that no buffer slot is currently bound to the texture. Note, Loading @@ -380,6 +331,17 @@ private: // reset mCurrentTexture to INVALID_BUFFER_SLOT. int mCurrentTexture; // Cached image used for rendering the current texture through GPU // composition, which contains the cached image after freeBufferLocked is // called on the current buffer. Whenever latchBuffer is called, this is // expected to be cleared. Then, if bindTexImage is called before the next // buffer is acquired, then this image is bound. std::unique_ptr<renderengine::Image> mCurrentTextureImageFreed; // Cached images used for rendering the current texture through GPU // composition. std::unique_ptr<renderengine::Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS]; // A release that is pending on the receipt of a new release fence from // presentDisplay PendingRelease mPendingRelease; Loading services/surfaceflinger/BufferQueueLayer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -216,7 +216,7 @@ void BufferQueueLayer::setFilteringEnabled(bool enabled) { return mConsumer->setFilteringEnabled(enabled); } status_t BufferQueueLayer::bindTextureImage() const { status_t BufferQueueLayer::bindTextureImage() { return mConsumer->bindTextureImage(); } Loading services/surfaceflinger/BufferQueueLayer.h +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ private: void setFilteringEnabled(bool enabled) override; status_t bindTextureImage() const override; status_t bindTextureImage() override; status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, const sp<Fence>& releaseFence) override; Loading Loading
services/surfaceflinger/BufferLayer.h +1 −1 Original line number Diff line number Diff line Loading @@ -138,7 +138,7 @@ private: virtual void setFilteringEnabled(bool enabled) = 0; virtual status_t bindTextureImage() const = 0; virtual status_t bindTextureImage() = 0; virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, const sp<Fence>& flushFence) = 0; Loading
services/surfaceflinger/BufferLayerConsumer.cpp +53 −68 Original line number Diff line number Diff line Loading @@ -111,12 +111,6 @@ status_t BufferLayerConsumer::updateTexImage(BufferRejecter* rejecter, nsecs_t e return NO_INIT; } // Make sure RenderEngine is current if (!mRE.isCurrent()) { BLC_LOGE("updateTexImage: RenderEngine is not current"); return INVALID_OPERATION; } BufferItem item; // Acquire the next buffer. Loading Loading @@ -185,8 +179,7 @@ void BufferLayerConsumer::setReleaseFence(const sp<Fence>& fence) { return; } auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer : mCurrentTextureImage->graphicBuffer(); auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer : mCurrentTextureBuffer; auto err = addReleaseFence(slot, buffer, fence); if (err != OK) { BLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", strerror(-err), err); Loading Loading @@ -222,10 +215,9 @@ status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t pres } // If item->mGraphicBuffer is not null, this buffer has not been acquired // before, so any prior EglImage created is using a stale buffer. This // replaces any old EglImage with a new one (using the new buffer). // before. if (item->mGraphicBuffer != nullptr) { mImages[item->mSlot] = new Image(item->mGraphicBuffer, mRE); mImages[item->mSlot] = nullptr; } return NO_ERROR; Loading @@ -252,19 +244,18 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, mCurrentTextureImage != nullptr ? mCurrentTextureImage->graphicBufferHandle() : 0, slot, mSlots[slot].mGraphicBuffer->handle); mCurrentTextureBuffer != nullptr ? mCurrentTextureBuffer->handle : 0, slot, mSlots[slot].mGraphicBuffer->handle); // Hang onto the pointer so that it isn't freed in the call to // releaseBufferLocked() if we're in shared buffer mode and both buffers are // the same. sp<Image> nextTextureImage = mImages[slot]; sp<GraphicBuffer> nextTextureBuffer = mSlots[slot].mGraphicBuffer; // release old buffer if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { status_t status = releaseBufferLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer()); status_t status = releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer); if (status < NO_ERROR) { BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); Loading @@ -273,14 +264,15 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } } else { pendingRelease->currentTexture = mCurrentTexture; pendingRelease->graphicBuffer = mCurrentTextureImage->graphicBuffer(); pendingRelease->graphicBuffer = mCurrentTextureBuffer; pendingRelease->isPending = true; } } // Update the BufferLayerConsumer state. mCurrentTexture = slot; mCurrentTextureImage = nextTextureImage; mCurrentTextureBuffer = nextTextureBuffer; mCurrentTextureImageFreed = nullptr; mCurrentCrop = item.mCrop; mCurrentTransform = item.mTransform; mCurrentScalingMode = item.mScalingMode; Loading @@ -301,22 +293,46 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, status_t BufferLayerConsumer::bindTextureImageLocked() { ATRACE_CALL(); mRE.checkErrors(); if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureImage == nullptr) { // It is possible for the current slot's buffer to be freed before a new one // is bound. In that scenario we still want to bind the image. if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT && mCurrentTextureBuffer == nullptr) { BLC_LOGE("bindTextureImage: no currently-bound texture"); mRE.bindExternalTextureImage(mTexName, *mRE.createImage()); return NO_INIT; } status_t err = mCurrentTextureImage->createIfNeeded(); if (err != NO_ERROR) { renderengine::Image* imageToRender; // mCurrentTextureImageFreed is non-null iff mCurrentTexture == // BufferQueue::INVALID_BUFFER_SLOT, so we can omit that check. if (mCurrentTextureImageFreed) { imageToRender = mCurrentTextureImageFreed.get(); } else if (mImages[mCurrentTexture]) { imageToRender = mImages[mCurrentTexture].get(); } else { std::unique_ptr<renderengine::Image> image = mRE.createImage(); bool success = image->setNativeWindowBuffer(mCurrentTextureBuffer->getNativeBuffer(), mCurrentTextureBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); if (!success) { BLC_LOGE("bindTextureImage: Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d", mCurrentTextureBuffer->getWidth(), mCurrentTextureBuffer->getHeight(), mCurrentTextureBuffer->getStride(), mCurrentTextureBuffer->getUsage(), mCurrentTextureBuffer->getPixelFormat()); BLC_LOGW("bindTextureImage: can't create image on slot=%d", mCurrentTexture); mRE.bindExternalTextureImage(mTexName, *mRE.createImage()); mRE.bindExternalTextureImage(mTexName, *image); return UNKNOWN_ERROR; } imageToRender = image.get(); // Cache the image here so that we can reuse it. mImages[mCurrentTexture] = std::move(image); } mRE.bindExternalTextureImage(mTexName, mCurrentTextureImage->image()); mRE.bindExternalTextureImage(mTexName, *imageToRender); // Wait for the new buffer to be ready. return doFenceWaitLocked(); Loading @@ -333,8 +349,7 @@ status_t BufferLayerConsumer::syncForReleaseLocked(const sp<Fence>& releaseFence return UNKNOWN_ERROR; } status_t err = addReleaseFenceLocked(mCurrentTexture, mCurrentTextureImage->graphicBuffer(), releaseFence); addReleaseFenceLocked(mCurrentTexture, mCurrentTextureBuffer, releaseFence); if (err != OK) { BLC_LOGE("syncForReleaseLocked: error adding release fence: " "%s (%d)", Loading @@ -361,24 +376,22 @@ void BufferLayerConsumer::setFilteringEnabled(bool enabled) { bool needsRecompute = mFilteringEnabled != enabled; mFilteringEnabled = enabled; if (needsRecompute && mCurrentTextureImage == nullptr) { BLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == nullptr"); if (needsRecompute && mCurrentTextureBuffer == nullptr) { BLC_LOGD("setFilteringEnabled called with mCurrentTextureBuffer == nullptr"); } if (needsRecompute && mCurrentTextureImage != nullptr) { if (needsRecompute && mCurrentTextureBuffer != nullptr) { computeCurrentTransformMatrixLocked(); } } void BufferLayerConsumer::computeCurrentTransformMatrixLocked() { BLC_LOGV("computeCurrentTransformMatrixLocked"); sp<GraphicBuffer> buf = (mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer(); if (buf == nullptr) { if (mCurrentTextureBuffer == nullptr) { BLC_LOGD("computeCurrentTransformMatrixLocked: " "mCurrentTextureImage is nullptr"); "mCurrentTextureBuffer is nullptr"); } GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, buf, mCurrentCrop, GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, mCurrentTextureBuffer, mCurrentCrop, mCurrentTransform, mFilteringEnabled); } Loading Loading @@ -427,7 +440,7 @@ sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot) const { *outSlot = mCurrentTexture; } return (mCurrentTextureImage == nullptr) ? nullptr : mCurrentTextureImage->graphicBuffer(); return mCurrentTextureBuffer; } Rect BufferLayerConsumer::getCurrentCrop() const { Loading Loading @@ -458,11 +471,6 @@ std::shared_ptr<FenceTime> BufferLayerConsumer::getCurrentFenceTime() const { } status_t BufferLayerConsumer::doFenceWaitLocked() const { if (!mRE.isCurrent()) { BLC_LOGE("doFenceWait: RenderEngine is not current"); return INVALID_OPERATION; } if (mCurrentFence->isValid()) { if (mRE.useWaitSync()) { base::unique_fd fenceFd(mCurrentFence->dup()); Loading Loading @@ -490,8 +498,10 @@ void BufferLayerConsumer::freeBufferLocked(int slotIndex) { BLC_LOGV("freeBufferLocked: slotIndex=%d", slotIndex); if (slotIndex == mCurrentTexture) { mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT; mCurrentTextureImageFreed = std::move(mImages[slotIndex]); } else { mImages[slotIndex] = nullptr; } mImages[slotIndex].clear(); ConsumerBase::freeBufferLocked(slotIndex); } Loading Loading @@ -530,7 +540,7 @@ void BufferLayerConsumer::addAndGetFrameTimestamps(const NewFrameEventsEntry* ne void BufferLayerConsumer::abandonLocked() { BLC_LOGV("abandonLocked"); mCurrentTextureImage.clear(); mCurrentTextureBuffer.clear(); ConsumerBase::abandonLocked(); } Loading @@ -548,29 +558,4 @@ void BufferLayerConsumer::dumpLocked(String8& result, const char* prefix) const ConsumerBase::dumpLocked(result, prefix); } BufferLayerConsumer::Image::Image(sp<GraphicBuffer> graphicBuffer, renderengine::RenderEngine& engine) : mGraphicBuffer(graphicBuffer), mImage{engine.createImage()}, mCreated(false), mCropWidth(0), mCropHeight(0) {} BufferLayerConsumer::Image::~Image() = default; status_t BufferLayerConsumer::Image::createIfNeeded() { if (mCreated) return OK; mCreated = mImage->setNativeWindowBuffer(mGraphicBuffer->getNativeBuffer(), mGraphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED); if (!mCreated) { const sp<GraphicBuffer>& buffer = mGraphicBuffer; ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d", buffer->getWidth(), buffer->getHeight(), buffer->getStride(), buffer->getUsage(), buffer->getPixelFormat()); } return mCreated ? OK : UNKNOWN_ERROR; } }; // namespace android
services/surfaceflinger/BufferLayerConsumer.h +17 −55 Original line number Diff line number Diff line Loading @@ -185,8 +185,7 @@ protected: // specific info in addition to the ConsumerBase behavior. virtual void dumpLocked(String8& result, const char* prefix) const; // acquireBufferLocked overrides the ConsumerBase method to update the // mImages array in addition to the ConsumerBase behavior. // See ConsumerBase::acquireBufferLocked virtual status_t acquireBufferLocked(BufferItem* item, nsecs_t presentWhen, uint64_t maxFrameNumber = 0) override; Loading @@ -210,53 +209,14 @@ protected: PendingRelease* pendingRelease = nullptr, const sp<Fence>& releaseFence = Fence::NO_FENCE); // Binds mTexName and the current buffer to TEXTURE_EXTERNAL target. Uses // mCurrentTexture if it's set, mCurrentTextureImage if not. If the // bind succeeds, this calls doFenceWait. // Binds mTexName and the current buffer to TEXTURE_EXTERNAL target. // If the bind succeeds, this calls doFenceWait. status_t bindTextureImageLocked(); private: // Image is a utility class for tracking and creating renderengine::Images. There // is primarily just one image per slot, but there is also special cases: // - After freeBuffer, we must still keep the current image/buffer // Reference counting renderengine::Images lets us handle all these cases easily while // also only creating new renderengine::Images from buffers when required. class Image : public LightRefBase<Image> { public: Image(sp<GraphicBuffer> graphicBuffer, renderengine::RenderEngine& engine); Image(const Image& rhs) = delete; Image& operator=(const Image& rhs) = delete; // createIfNeeded creates an renderengine::Image if we haven't created one yet. status_t createIfNeeded(); const sp<GraphicBuffer>& graphicBuffer() { return mGraphicBuffer; } const native_handle* graphicBufferHandle() { return mGraphicBuffer == nullptr ? nullptr : mGraphicBuffer->handle; } const renderengine::Image& image() const { return *mImage; } private: // Only allow instantiation using ref counting. friend class LightRefBase<Image>; virtual ~Image(); // mGraphicBuffer is the buffer that was used to create this image. sp<GraphicBuffer> mGraphicBuffer; // mImage is the image created from mGraphicBuffer. std::unique_ptr<renderengine::Image> mImage; bool mCreated; int32_t mCropWidth; int32_t mCropHeight; }; // 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 renderengine::Image in that slot. Otherwise it has no // effect. // that slot. Otherwise it has no effect. // // This method must be called with mMutex locked. virtual void freeBufferLocked(int slotIndex); Loading Loading @@ -290,10 +250,10 @@ private: // consume buffers as hardware textures. static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE; // mCurrentTextureImage is the Image/buffer of the current texture. It's // mCurrentTextureImage is the buffer containing the current texture. It's // possible that this buffer is not associated with any buffer slot, so we // must track it separately in order to support the getCurrentBuffer method. sp<Image> mCurrentTextureImage; sp<GraphicBuffer> mCurrentTextureBuffer; // mCurrentCrop is the crop rectangle that applies to the current texture. // It gets set each time updateTexImage is called. Loading Loading @@ -363,15 +323,6 @@ private: wp<ContentsChangedListener> mContentsChangedListener; // mImages stores the buffers that have been allocated by the BufferQueue // for each buffer slot. It is initialized to null pointers, and gets // filled in with the result of BufferQueue::acquire when the // client dequeues a buffer from a // 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. sp<Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS]; // mCurrentTexture is the buffer slot index of the buffer that is currently // bound to the RenderEngine texture. It is initialized to INVALID_BUFFER_SLOT, // indicating that no buffer slot is currently bound to the texture. Note, Loading @@ -380,6 +331,17 @@ private: // reset mCurrentTexture to INVALID_BUFFER_SLOT. int mCurrentTexture; // Cached image used for rendering the current texture through GPU // composition, which contains the cached image after freeBufferLocked is // called on the current buffer. Whenever latchBuffer is called, this is // expected to be cleared. Then, if bindTexImage is called before the next // buffer is acquired, then this image is bound. std::unique_ptr<renderengine::Image> mCurrentTextureImageFreed; // Cached images used for rendering the current texture through GPU // composition. std::unique_ptr<renderengine::Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS]; // A release that is pending on the receipt of a new release fence from // presentDisplay PendingRelease mPendingRelease; Loading
services/surfaceflinger/BufferQueueLayer.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -216,7 +216,7 @@ void BufferQueueLayer::setFilteringEnabled(bool enabled) { return mConsumer->setFilteringEnabled(enabled); } status_t BufferQueueLayer::bindTextureImage() const { status_t BufferQueueLayer::bindTextureImage() { return mConsumer->bindTextureImage(); } Loading
services/surfaceflinger/BufferQueueLayer.h +1 −1 Original line number Diff line number Diff line Loading @@ -89,7 +89,7 @@ private: void setFilteringEnabled(bool enabled) override; status_t bindTextureImage() const override; status_t bindTextureImage() override; status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, const sp<Fence>& releaseFence) override; Loading