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

Commit 18d61067 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Cleanup AutoBackendTexture to make it more difficult to leak resources" into sc-dev

parents 4de5bbe7 d8fdae33
Loading
Loading
Loading
Loading
+14 −4
Original line number Original line Diff line number Diff line
@@ -29,7 +29,8 @@ namespace renderengine {
namespace skia {
namespace skia {


AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer,
AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer* buffer,
                                       bool isRender) {
                                       bool isOutputBuffer)
      : mIsOutputBuffer(isOutputBuffer) {
    ATRACE_CALL();
    ATRACE_CALL();
    AHardwareBuffer_Desc desc;
    AHardwareBuffer_Desc desc;
    AHardwareBuffer_describe(buffer, &desc);
    AHardwareBuffer_describe(buffer, &desc);
@@ -40,8 +41,12 @@ AutoBackendTexture::AutoBackendTexture(GrDirectContext* context, AHardwareBuffer
            GrAHardwareBufferUtils::MakeBackendTexture(context, buffer, desc.width, desc.height,
            GrAHardwareBufferUtils::MakeBackendTexture(context, buffer, desc.width, desc.height,
                                                       &mDeleteProc, &mUpdateProc, &mImageCtx,
                                                       &mDeleteProc, &mUpdateProc, &mImageCtx,
                                                       createProtectedImage, backendFormat,
                                                       createProtectedImage, backendFormat,
                                                       isRender);
                                                       isOutputBuffer);
    mColorType = GrAHardwareBufferUtils::GetSkColorTypeFromBufferFormat(desc.format);
    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) {
void AutoBackendTexture::unref(bool releaseLocalResources) {
@@ -92,13 +97,16 @@ sk_sp<SkImage> AutoBackendTexture::makeImage(ui::Dataspace dataspace, SkAlphaTyp


    mImage = image;
    mImage = image;
    mDataspace = dataspace;
    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;
    return mImage;
}
}


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


    mDataspace = 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;
    return mSurface;
}
}


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

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


        AutoBackendTexture* getTexture() const { return mTexture; }
        ~LocalRef() {

        DISALLOW_COPY_AND_ASSIGN(LocalRef);

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


            mTexture = texture;
        // Makes a new SkImage from the texture content.
            if (mTexture != nullptr) {
        // As SkImages are immutable but buffer content is not, we create
                mTexture->ref();
        // 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;
        AutoBackendTexture* mTexture = nullptr;
    };
    };


private:
    // Creates a GrBackendTexture whose contents come from the provided buffer.
    // 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++; }
    void ref() { mUsageCount++; }


@@ -85,10 +93,6 @@ public:
    // Makes a new SkSurface from the texture content, if needed.
    // Makes a new SkSurface from the texture content, if needed.
    sk_sp<SkSurface> getOrCreateSurface(ui::Dataspace dataspace, GrDirectContext* context);
    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;
    GrBackendTexture mBackendTexture;
    GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
    GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
    GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
    GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
@@ -99,6 +103,7 @@ private:


    int mUsageCount = 0;
    int mUsageCount = 0;


    const bool mIsOutputBuffer;
    sk_sp<SkImage> mImage = nullptr;
    sk_sp<SkImage> mImage = nullptr;
    sk_sp<SkSurface> mSurface = nullptr;
    sk_sp<SkSurface> mSurface = nullptr;
    ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
    ui::Dataspace mDataspace = ui::Dataspace::UNKNOWN;
+17 −16
Original line number Original line 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()) {
    if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) {
        std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
        std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef =
                std::make_shared<AutoBackendTexture::LocalRef>(
                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
                        new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(),
                                                               buffer->toAHardwareBuffer(),
                                               isRenderable));
                                                               isRenderable);
        cache.insert({buffer->getId(), imageTextureRef});
        cache.insert({buffer->getId(), imageTextureRef});
    }
    }
    // restore the original state of the protected context if necessary
    // 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()) {
    if (const auto& it = cache.find(buffer->getBuffer()->getId()); it != cache.end()) {
        surfaceTextureRef = it->second;
        surfaceTextureRef = it->second;
    } else {
    } else {
        surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
        surfaceTextureRef =
                new AutoBackendTexture(grContext.get(), buffer->getBuffer()->toAHardwareBuffer(),
                std::make_shared<AutoBackendTexture::LocalRef>(grContext.get(),
                                       true));
                                                               buffer->getBuffer()
                                                                       ->toAHardwareBuffer(),
                                                               true);
    }
    }


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


    SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
    SkCanvas* dstCanvas = mCapture->tryCapture(dstSurface.get());
    if (dstCanvas == nullptr) {
    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
                // 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
                // we didn't find anything in the cache then we intentionally did not cache this
                // buffer's resources.
                // buffer's resources.
                imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(
                imageTextureRef = std::make_shared<
                        new AutoBackendTexture(grContext.get(),
                        AutoBackendTexture::LocalRef>(grContext.get(),
                                                      item.buffer->getBuffer()->toAHardwareBuffer(),
                                                      item.buffer->getBuffer()->toAHardwareBuffer(),
                                               false));
                                                      false);
            }
            }


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