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

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

Merge "Adding an image cache to be behind drawLayers."

parents 75c14637 539319fb
Loading
Loading
Loading
Loading
+41 −2
Original line number Diff line number Diff line
@@ -608,7 +608,17 @@ void GLESRenderEngine::bindExternalTextureImage(uint32_t texName, const Image& i
}

status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer,
                                                     sp<Fence> bufferFence) {
                                                     sp<Fence> bufferFence, bool readCache,
                                                     bool persistCache) {
    if (readCache) {
        auto cachedImage = mImageCache.find(buffer->getId());

        if (cachedImage != mImageCache.end()) {
            bindExternalTextureImage(texName, *cachedImage->second);
            return NO_ERROR;
        }
    }

    std::unique_ptr<Image> newImage = createImage();

    bool created = newImage->setNativeWindowBuffer(buffer->getNativeBuffer(),
@@ -644,9 +654,35 @@ status_t GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, sp<Graphi
        }
    }

    // We don't always want to persist to the cache, e.g. on older devices we
    // might bind for synchronization purpoeses, but that might leak if we never
    // call drawLayers again, so it's just better to recreate the image again
    // if needed when we draw.
    if (persistCache) {
        mImageCache.insert(std::make_pair(buffer->getId(), std::move(newImage)));
    }

    return NO_ERROR;
}

void GLESRenderEngine::evictImages(const std::vector<LayerSettings>& layers) {
    // destroy old image references that we're not going to draw with.
    std::unordered_set<uint64_t> bufIds;
    for (auto layer : layers) {
        if (layer.source.buffer.buffer != nullptr) {
            bufIds.emplace(layer.source.buffer.buffer->getId());
        }
    }

    for (auto it = mImageCache.begin(); it != mImageCache.end();) {
        if (bufIds.count(it->first) == 0) {
            it = mImageCache.erase(it);
        } else {
            it++;
        }
    }
}

FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) {
    // Translate win by the rounded corners rect coordinates, to have all values in
    // layer coordinate space.
@@ -748,6 +784,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,
        return fbo.getStatus();
    }

    evictImages(layers);

    setViewportAndProjection(display.physicalDisplay, display.clip);

    setOutputDataSpace(display.outputDataspace);
@@ -781,8 +819,9 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display,

            sp<GraphicBuffer> gBuf = layer.source.buffer.buffer;

            bool readCache = layer.source.buffer.cacheHint == Buffer::CachingHint::USE_CACHE;
            bindExternalTextureBuffer(layer.source.buffer.textureName, gBuf,
                                      layer.source.buffer.fence);
                                      layer.source.buffer.fence, readCache, /*persistCache=*/true);

            usePremultipliedAlpha = layer.source.buffer.usePremultipliedAlpha;
            Texture texture(Texture::TEXTURE_EXTERNAL, layer.source.buffer.textureName);
+8 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
#include <GLES2/gl2.h>
#include <renderengine/RenderEngine.h>
#include <renderengine/private/Description.h>
#include <unordered_map>

#define EGL_NO_CONFIG ((EGLConfig)0)

@@ -133,7 +134,10 @@ private:
    // Defines the viewport, and sets the projection matrix to the projection
    // defined by the clip.
    void setViewportAndProjection(Rect viewport, Rect clip);
    status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence);
    status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence,
                                       bool readCache, bool persistCache);
    // Evicts stale images from the buffer cache.
    void evictImages(const std::vector<LayerSettings>& layers);
    // Computes the cropping window for the layer and sets up cropping
    // coordinates for the mesh.
    FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh);
@@ -179,6 +183,9 @@ private:
    // supports sRGB, DisplayP3 color spaces.
    const bool mUseColorManagement = false;

    // Cache of GL images that we'll store per GraphicBuffer ID
    std::unordered_map<uint64_t, std::unique_ptr<Image>> mImageCache;

    class FlushTracer {
    public:
        FlushTracer(GLESRenderEngine* engine);
+13 −0
Original line number Diff line number Diff line
@@ -32,6 +32,16 @@ namespace renderengine {

// Metadata describing the input buffer to render from.
struct Buffer {
    // Hint for whether to use the Image cache or not.
    // If NO_CACHE is specified, then upload the contents of the GraphicBuffer
    // to the GPU, without checking against any implementation defined cache.
    // If USE_CACHE is specified, then check against an implementation defined
    // cache first. If there is an Image cached for the given GraphicBuffer id,
    // then use that instead of the provided buffer contents. If there is no
    // cached image or the RenderEngine implementation does not support caching,
    // then use the GraphicBuffer contents.
    enum class CachingHint { NO_CACHE, USE_CACHE };

    // Buffer containing the image that we will render.
    // If buffer == nullptr, then the rest of the fields in this struct will be
    // ignored.
@@ -40,6 +50,9 @@ struct Buffer {
    // Fence that will fire when the buffer is ready to be bound.
    sp<Fence> fence = nullptr;

    // Caching hint to use when uploading buffer contents.
    CachingHint cacheHint = CachingHint::NO_CACHE;

    // Texture identifier to bind the external texture to.
    // TODO(alecmouri): This is GL-specific...make the type backend-agnostic.
    uint32_t textureName = 0;