Loading libs/renderengine/gl/GLESRenderEngine.cpp +41 −2 Original line number Diff line number Diff line Loading @@ -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(), Loading Loading @@ -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. Loading Loading @@ -748,6 +784,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, return fbo.getStatus(); } evictImages(layers); setViewportAndProjection(display.physicalDisplay, display.clip); setOutputDataSpace(display.outputDataspace); Loading Loading @@ -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); Loading libs/renderengine/gl/GLESRenderEngine.h +8 −1 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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); Loading Loading @@ -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); Loading libs/renderengine/include/renderengine/LayerSettings.h +13 −0 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading Loading
libs/renderengine/gl/GLESRenderEngine.cpp +41 −2 Original line number Diff line number Diff line Loading @@ -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(), Loading Loading @@ -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. Loading Loading @@ -748,6 +784,8 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, return fbo.getStatus(); } evictImages(layers); setViewportAndProjection(display.physicalDisplay, display.clip); setOutputDataSpace(display.outputDataspace); Loading Loading @@ -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); Loading
libs/renderengine/gl/GLESRenderEngine.h +8 −1 Original line number Diff line number Diff line Loading @@ -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) Loading Loading @@ -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); Loading Loading @@ -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); Loading
libs/renderengine/include/renderengine/LayerSettings.h +13 −0 Original line number Diff line number Diff line Loading @@ -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. Loading @@ -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; Loading