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

Commit a90a570e authored by Alec Mouri's avatar Alec Mouri
Browse files

Revert "Revert "Add ExternalTexture class into RenderEngine inte..."

Revert submission 14199598-revert-14086921-renderengine-external-tex-QJNBWQMQEU

Reason for revert: Prepare for relanding
Reverted Changes:
I01e65a7f4:Revert "Update WaylandRenderSurface to accomodate ...
I7d58118c1:Revert "Update Readback VTS to align with RenderEn...
I1501890f4:Revert "Add ExternalTexture class into RenderEngin...

Added the following fixes:
1. CachedSet renders to intermediate texture variable rather than
mTexture directly, since mTexture is not guaranteed to be nonnull.
2. Add null check when setting new buffer in BLAST.

Bug: 185524947
Bug: 180767535
Test: builds, boots
Test: librenderengine_test
Change-Id: I52ea82e24336b496d996bbe3e445db0affe1abb8
parent 7f0c9b1f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ filegroup {
    name: "librenderengine_sources",
    srcs: [
        "Description.cpp",
        "ExternalTexture.cpp",
        "Mesh.cpp",
        "RenderEngine.cpp",
        "Texture.cpp",
+43 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <renderengine/ExternalTexture.h>
#include <renderengine/RenderEngine.h>
#include <ui/GraphicBuffer.h>

#include "log/log_main.h"

namespace android::renderengine {

ExternalTexture::ExternalTexture(const sp<GraphicBuffer>& buffer, RenderEngine& renderEngine,
                                 uint32_t usage)
      : mBuffer(buffer), mRenderEngine(renderEngine) {
    LOG_ALWAYS_FATAL_IF(buffer == nullptr,
                        "Attempted to bind a null buffer to an external texture!");
    // GLESRenderEngine has a separate texture cache for output buffers,
    if (usage == Usage::WRITEABLE &&
        (mRenderEngine.getRenderEngineType() == RenderEngine::RenderEngineType::GLES ||
         mRenderEngine.getRenderEngineType() == RenderEngine::RenderEngineType::THREADED)) {
        return;
    }
    mRenderEngine.mapExternalTextureBuffer(mBuffer, usage & Usage::WRITEABLE);
}

ExternalTexture::~ExternalTexture() {
    mRenderEngine.unmapExternalTextureBuffer(mBuffer);
}

} // namespace android::renderengine
+17 −13
Original line number Diff line number Diff line
@@ -746,7 +746,8 @@ void GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, const sp<Grap
    return;
}

void GLESRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
void GLESRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer,
                                                bool /*isRenderable*/) {
    ATRACE_CALL();
    mImageManager->cacheAsync(buffer, nullptr);
}
@@ -797,8 +798,8 @@ status_t GLESRenderEngine::cacheExternalTextureBufferInternal(const sp<GraphicBu
    return NO_ERROR;
}

void GLESRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) {
    mImageManager->releaseAsync(bufferId, nullptr);
void GLESRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) {
    mImageManager->releaseAsync(buffer->getId(), nullptr);
}

std::shared_ptr<ImageManager::Barrier> GLESRenderEngine::unbindExternalTextureBufferForTesting(
@@ -1102,7 +1103,7 @@ EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer

status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
                                      const std::vector<const LayerSettings*>& layers,
                                      const sp<GraphicBuffer>& buffer,
                                      const std::shared_ptr<ExternalTexture>& buffer,
                                      const bool useFramebufferCache, base::unique_fd&& bufferFence,
                                      base::unique_fd* drawFence) {
    ATRACE_CALL();
@@ -1125,7 +1126,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
        return BAD_VALUE;
    }

    validateOutputBufferUsage(buffer);
    validateOutputBufferUsage(buffer->getBuffer());

    std::unique_ptr<BindNativeBufferAsFramebuffer> fbo;
    // Gathering layers that requested blur, we'll need them to decide when to render to an
@@ -1142,11 +1143,13 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,

    if (blurLayersSize == 0) {
        fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
                                                              buffer.get()->getNativeBuffer(),
                                                              buffer->getBuffer()
                                                                      .get()
                                                                      ->getNativeBuffer(),
                                                              useFramebufferCache);
        if (fbo->getStatus() != NO_ERROR) {
            ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
                  buffer->handle);
                  buffer->getBuffer()->handle);
            checkErrors();
            return fbo->getStatus();
        }
@@ -1157,7 +1160,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
                mBlurFilter->setAsDrawTarget(display, blurLayers.front()->backgroundBlurRadius);
        if (status != NO_ERROR) {
            ALOGE("Failed to prepare blur filter! Aborting GPU composition for buffer (%p).",
                  buffer->handle);
                  buffer->getBuffer()->handle);
            checkErrors();
            return status;
        }
@@ -1194,7 +1197,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
            auto status = mBlurFilter->prepare();
            if (status != NO_ERROR) {
                ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
                      buffer->handle);
                      buffer->getBuffer()->handle);
                checkErrors("Can't render first blur pass");
                return status;
            }
@@ -1203,6 +1206,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
                // Done blurring, time to bind the native FBO and render our blur onto it.
                fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this,
                                                                      buffer.get()
                                                                              ->getBuffer()
                                                                              ->getNativeBuffer(),
                                                                      useFramebufferCache);
                status = fbo->getStatus();
@@ -1215,7 +1219,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
            }
            if (status != NO_ERROR) {
                ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).",
                      buffer->handle);
                      buffer->getBuffer()->handle);
                checkErrors("Can't bind native framebuffer");
                return status;
            }
@@ -1223,7 +1227,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
            status = mBlurFilter->render(blurLayersSize > 1);
            if (status != NO_ERROR) {
                ALOGE("Failed to render blur effect! Aborting GPU composition for buffer (%p).",
                      buffer->handle);
                      buffer->getBuffer()->handle);
                checkErrors("Can't render blur filter");
                return status;
            }
@@ -1250,7 +1254,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
            disableTexture = false;
            isOpaque = layer->source.buffer.isOpaque;

            sp<GraphicBuffer> gBuf = layer->source.buffer.buffer;
            sp<GraphicBuffer> gBuf = layer->source.buffer.buffer->getBuffer();
            validateInputBufferUsage(gBuf);
            bindExternalTextureBuffer(layer->source.buffer.textureName, gBuf,
                                      layer->source.buffer.fence);
@@ -1274,7 +1278,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,

            // Do not cache protected EGLImage, protected memory is limited.
            if (gBuf->getUsage() & GRALLOC_USAGE_PROTECTED) {
                unbindExternalTextureBuffer(gBuf->getId());
                unmapExternalTextureBuffer(gBuf);
            }
        }

+6 −5
Original line number Diff line number Diff line
@@ -60,16 +60,14 @@ public:
    void primeCache() override;
    void genTextures(size_t count, uint32_t* names) override;
    void deleteTextures(size_t count, uint32_t const* names) override;
    void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);
    void unbindExternalTextureBuffer(uint64_t bufferId) EXCLUDES(mRenderingMutex);

    bool isProtected() const override { return mInProtectedContext; }
    bool supportsProtectedContent() const override;
    bool useProtectedContext(bool useProtectedContext) override;
    status_t drawLayers(const DisplaySettings& display,
                        const std::vector<const LayerSettings*>& layers,
                        const sp<GraphicBuffer>& buffer, const bool useFramebufferCache,
                        base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
                        const std::shared_ptr<ExternalTexture>& buffer,
                        const bool useFramebufferCache, base::unique_fd&& bufferFence,
                        base::unique_fd* drawFence) override;
    bool cleanupPostRender(CleanupMode mode) override;
    int getContextPriority() override;
    bool supportsBackgroundBlur() override { return mBlurFilter != nullptr; }
@@ -105,6 +103,9 @@ protected:
            EXCLUDES(mFramebufferImageCacheMutex);
    size_t getMaxTextureSize() const override;
    size_t getMaxViewportDims() const override;
    void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable)
            EXCLUDES(mRenderingMutex);
    void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) EXCLUDES(mRenderingMutex);

private:
    friend class BindNativeBufferAsFramebuffer;
+61 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <android-base/macros.h>
#include <ui/GraphicBuffer.h>

namespace android::renderengine {

class RenderEngine;

/**
 * Manages GPU image resources on behalf of clients using RenderEngine.
 *
 * Clients of RenderEngine are required to wrap their GraphicBuffer objects as an ExternalTexture,
 * which is then mapped into GPU resources required by RenderEngine. When a client no longer needs
 * to use the GraphicBuffer as input into RenderEngine::drawLayers, then the client should delete
 * their ExternalTexture so that resources may be freed.
 */
class ExternalTexture {
public:
    // Usage specifies the rendering intent for the buffer.
    enum Usage : uint32_t {
        // When a buffer is not READABLE but is WRITEABLE, then GLESRenderEngine will use that as a
        // hint to load the buffer into a separate cache
        READABLE = 1 << 0,

        // The buffer needs to be mapped as a 2D texture if set, otherwise must be mapped as an
        // external texture
        WRITEABLE = 1 << 1,
    };
    // Creates an ExternalTexture for the provided buffer and RenderEngine instance, with the given
    // usage hint of type Usage.
    ExternalTexture(const sp<GraphicBuffer>& buffer, RenderEngine& renderEngine, uint32_t usage);

    ~ExternalTexture();

    // Retrieves the buffer that is bound to this texture.
    const sp<GraphicBuffer>& getBuffer() const { return mBuffer; }

private:
    sp<GraphicBuffer> mBuffer;
    RenderEngine& mRenderEngine;
    DISALLOW_COPY_AND_ASSIGN(ExternalTexture);
};

} // namespace android::renderengine
Loading