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

Commit 18f6d352 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Cleanup AutoBackendTexture to make it more difficult to leak resources"...

Merge "Cleanup AutoBackendTexture to make it more difficult to leak resources" into sc-dev am: 18d61067

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/14140628

Change-Id: Ic0aec9900fde4ce05f0e3b8af4101602b5be1b29
parents 5e458d19 18d61067
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -29,7 +29,8 @@ namespace renderengine {
namespace skia {

AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer,
                                       bool isRender) {
                                       bool isOutputBuffer)
      : mIsOutputBuffer(isOutputBuffer) {
    ATRACE_CALL();
    AHardwareBuffer_Desc desc;
    AHardwareBuffer_describe(buffer, &desc);
@@ -40,8 +41,12 @@ AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer
            GrAHardwareBufferUtils::MakeBackendTexture(context, buffer, desc.width, desc.height,
                                                       &mDeleteProc, &mUpdateProc, &mImageCtx,
                                                       createProtectedImage, backendFormat,
                                                       isRender);
                                                       isOutputBuffer);
    mColorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format);
    ALOGE_IF(!mBackendTexture.isValid(),
             "Failed to create a valid texture. [%p]:[%d,%d] isProtected:%d isWriteable:%d "
             "format:%d",
             this, desc.width, desc.height, isOutputBuffer, createProtectedImage, desc.format);
}

void AutoBackendTexture::unref(bool releaseLocalResources) {
@@ -92,13 +97,16 @@ sk_sp<SkImage> AutoBackendTexture::makeImage(ui::Dataspace dataspace, SkAlphaTyp

    mImage = image;
    mDataspace = dataspace;
    LOG_ALWAYS_FATAL_IF(mImage == nullptr, "Unable to generate SkImage from buffer");
    LOG_ALWAYS_FATAL_IF(mImage == nullptr,
                        "Unable to generate SkImage. isTextureValid:%d dataspace:%d",
                        mBackendTexture.isValid(), dataspace);
    return mImage;
}

sk_sp<SkSurface> AutoBackendTexture::getOrCreateSurface(ui::Dataspace dataspace,
                                                        GrDirectContext* context) {
    ATRACE_CALL();
    LOG_ALWAYS_FATAL_IF(!mIsOutputBuffer, "You can't generate a SkSurface for a read-only texture");
    if (!mSurface.get() || mDataspace != dataspace) {
        sk_sp<SkSurface> surface =
                SkSurface::MakeFromBackendTexture(context, mBackendTexture,
@@ -113,7 +121,9 @@ sk_sp<SkSurface> AutoBackendTexture::getOrCreateSurface(ui::Dataspace dataspace,
    }

    mDataspace = dataspace;
    LOG_ALWAYS_FATAL_IF(mSurface == nullptr, "Unable to generate SkSurface");
    LOG_ALWAYS_FATAL_IF(mSurface == nullptr,
                        "Unable to generate SkSurface. isTextureValid:%d dataspace:%d",
                        mBackendTexture.isValid(), dataspace);
    return mSurface;
}

+25 −20
Original line number Diff line number Diff line
@@ -41,34 +41,42 @@ public:
    // of shared ownership with Skia objects, so we wrap it here instead.
    class LocalRef {
    public:
        LocalRef(AutoBackendTexture* texture) { setTexture(texture); }

        ~LocalRef() {
            // Destroying the texture is the same as setting it to null
            setTexture(nullptr);
        LocalRef(GrDirectContext* context, AHardwareBuffer* buffer, bool isOutputBuffer) {
            mTexture = new AutoBackendTexture(context, buffer, isOutputBuffer);
            mTexture->ref();
        }

        AutoBackendTexture* getTexture() const { return mTexture; }

        DISALLOW_COPY_AND_ASSIGN(LocalRef);

    private:
        // Sets the texture to locally ref-track.
        void setTexture(AutoBackendTexture* texture) {
        ~LocalRef() {
            if (mTexture != nullptr) {
                mTexture->unref(true);
            }
        }

            mTexture = texture;
            if (mTexture != nullptr) {
                mTexture->ref();
        // Makes a new SkImage from the texture content.
        // As SkImages are immutable but buffer content is not, we create
        // a new SkImage every time.
        sk_sp<SkImage> makeImage(ui::Dataspace dataspace, SkAlphaType alphaType,
                                 GrDirectContext* context) {
            return mTexture->makeImage(dataspace, alphaType, context);
        }

        // Makes a new SkSurface from the texture content, if needed.
        sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context) {
            return mTexture->getOrCreateSurface(dataspace, context);
        }

        DISALLOW_COPY_AND_ASSIGN(LocalRef);

    private:
        AutoBackendTexture* mTexture = nullptr;
    };

private:
    // Creates a GrBackendTexture whose contents come from the provided buffer.
    AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isRender);
    AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer, bool isOutputBuffer);

    // The only way to invoke dtor is with unref, when mUsageCount is 0.
    ~AutoBackendTexture() {}

    void ref() { mUsageCount++; }

@@ -85,10 +93,6 @@ public:
    // Makes a new SkSurface from the texture content, if needed.
    sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context);

private:
    // The only way to invoke dtor is with unref, when mUsageCount is 0.
    ~AutoBackendTexture() {}

    GrBackendTexture mBackendTexture;
    GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
    GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
@@ -99,6 +103,7 @@ private:

    int mUsageCount = 0;

    const bool mIsOutputBuffer;
    sk_sp<SkImage> mImage = nullptr;
    sk_sp<SkSurface> mSurface = nullptr;
    ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
+17 −16
Original line number Diff line number Diff line
@@ -508,9 +508,9 @@ void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffe

    if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
        std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
                std::make_shared<AutoBackendTexture::LocalRef>(
                        new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(),
                                               isRenderable));
                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
                                                               buffer->toAHardwareBuffer(),
                                                               isRenderable);
        cache.insert({buffer->getId(), imageTextureRef});
    }
    // restore the original state of the protected context if necessary
@@ -669,15 +669,17 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
    if (const auto& it = cache.find(buffer->getBuffer()->getId()); it != cache.end()) {
        surfaceTextureRef = it->second;
    } else {
        surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
                new AutoBackendTexture(grContext.get(), buffer->getBuffer()->toAHardwareBuffer(),
                                       true));
        surfaceTextureRef =
                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
                                                               buffer->getBuffer()
                                                                       ->toAHardwareBuffer(),
                                                               true);
    }

    const ui::Dataspace dstDataspace =
            mUseColorManagement ? display.outputDataspace : ui::Dataspace::UNKNOWN;
    sk_sp<SkSurface> dstSurface =
            surfaceTextureRef->getTexture()->getOrCreateSurface(dstDataspace, grContext.get());
            surfaceTextureRef->getOrCreateSurface(dstDataspace, grContext.get());

    SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
    if (dstCanvas == nullptr) {
@@ -889,16 +891,15 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display,
                // it. If we're using skia, we're guaranteed to run on a dedicated GPU thread so if
                // we didn't find anything in the cache then we intentionally did not cache this
                // buffer's resources.
                imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
                        new AutoBackendTexture(grContext.get(),
                imageTextureRef = std::make_shared<
                        AutoBackendTexture::LocalRef>(grContext.get(),
                                                      item.buffer->getBuffer()->toAHardwareBuffer(),
                                               false));
                                                      false);
            }

            sk_sp<SkImage> image =
                    imageTextureRef->getTexture()->makeImage(layerDataspace,
                                                             item.usePremultipliedAlpha
                                                                     ? kPremul_SkAlphaType
                    imageTextureRef->makeImage(layerDataspace,
                                               item.usePremultipliedAlpha ? kPremul_SkAlphaType
                                                                          : kUnpremul_SkAlphaType,
                                               grContext.get());