diff options
author | 2021-04-15 16:27:01 +0000 | |
---|---|---|
committer | 2021-04-15 16:27:01 +0000 | |
commit | 617752fa9590d39930f7bcf46abaea8f2e1e1032 (patch) | |
tree | d25b577aaa7a8ffd432c63b9103bc296c6d1f7ed | |
parent | 2daef3c6ba72f364f9ac3859efc1cf2782fff67f (diff) |
Revert "Add ExternalTexture class into RenderEngine interface"
Revert submission 14086921-renderengine-external-tex
Reason for revert: Potential culprit for b/185361988
Reverted Changes:
I7796764e2:Update WaylandRenderSurface to accomodate interfac...
I13904eec4:Update Readback VTS to align with RenderEngine int...
I222c71e6e:Add ExternalTexture class into RenderEngine interf...
Change-Id: I1501890f4861a3df7ce273f1fe2ccdb275e2632c
53 files changed, 643 insertions, 803 deletions
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp index f395ab43d8..ec39137e24 100644 --- a/libs/renderengine/Android.bp +++ b/libs/renderengine/Android.bp @@ -48,7 +48,6 @@ filegroup { name: "librenderengine_sources", srcs: [ "Description.cpp", - "ExternalTexture.cpp", "Mesh.cpp", "RenderEngine.cpp", "Texture.cpp", diff --git a/libs/renderengine/ExternalTexture.cpp b/libs/renderengine/ExternalTexture.cpp deleted file mode 100644 index eabff58eba..0000000000 --- a/libs/renderengine/ExternalTexture.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp index d87315fdc2..a2963a7c33 100644 --- a/libs/renderengine/gl/GLESRenderEngine.cpp +++ b/libs/renderengine/gl/GLESRenderEngine.cpp @@ -746,8 +746,7 @@ void GLESRenderEngine::bindExternalTextureBuffer(uint32_t texName, const sp<Grap return; } -void GLESRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, - bool /*isRenderable*/) { +void GLESRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) { ATRACE_CALL(); mImageManager->cacheAsync(buffer, nullptr); } @@ -798,8 +797,8 @@ status_t GLESRenderEngine::cacheExternalTextureBufferInternal(const sp<GraphicBu return NO_ERROR; } -void GLESRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) { - mImageManager->releaseAsync(buffer->getId(), nullptr); +void GLESRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) { + mImageManager->releaseAsync(bufferId, nullptr); } std::shared_ptr<ImageManager::Barrier> GLESRenderEngine::unbindExternalTextureBufferForTesting( @@ -1103,7 +1102,7 @@ EGLImageKHR GLESRenderEngine::createFramebufferImageIfNeeded(ANativeWindowBuffer status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, - const std::shared_ptr<ExternalTexture>& buffer, + const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) { ATRACE_CALL(); @@ -1126,7 +1125,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, return BAD_VALUE; } - validateOutputBufferUsage(buffer->getBuffer()); + validateOutputBufferUsage(buffer); std::unique_ptr<BindNativeBufferAsFramebuffer> fbo; // Gathering layers that requested blur, we'll need them to decide when to render to an @@ -1143,13 +1142,11 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, if (blurLayersSize == 0) { fbo = std::make_unique<BindNativeBufferAsFramebuffer>(*this, - buffer->getBuffer() - .get() - ->getNativeBuffer(), + buffer.get()->getNativeBuffer(), useFramebufferCache); if (fbo->getStatus() != NO_ERROR) { ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).", - buffer->getBuffer()->handle); + buffer->handle); checkErrors(); return fbo->getStatus(); } @@ -1160,7 +1157,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->getBuffer()->handle); + buffer->handle); checkErrors(); return status; } @@ -1197,7 +1194,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->getBuffer()->handle); + buffer->handle); checkErrors("Can't render first blur pass"); return status; } @@ -1206,7 +1203,6 @@ 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(); @@ -1219,7 +1215,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, } if (status != NO_ERROR) { ALOGE("Failed to bind framebuffer! Aborting GPU composition for buffer (%p).", - buffer->getBuffer()->handle); + buffer->handle); checkErrors("Can't bind native framebuffer"); return status; } @@ -1227,7 +1223,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->getBuffer()->handle); + buffer->handle); checkErrors("Can't render blur filter"); return status; } @@ -1254,7 +1250,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, disableTexture = false; isOpaque = layer->source.buffer.isOpaque; - sp<GraphicBuffer> gBuf = layer->source.buffer.buffer->getBuffer(); + sp<GraphicBuffer> gBuf = layer->source.buffer.buffer; validateInputBufferUsage(gBuf); bindExternalTextureBuffer(layer->source.buffer.textureName, gBuf, layer->source.buffer.fence); @@ -1278,7 +1274,7 @@ status_t GLESRenderEngine::drawLayers(const DisplaySettings& display, // Do not cache protected EGLImage, protected memory is limited. if (gBuf->getUsage() & GRALLOC_USAGE_PROTECTED) { - unmapExternalTextureBuffer(gBuf); + unbindExternalTextureBuffer(gBuf->getId()); } } diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h index e7ed9c01fa..cd7a86bb0e 100644 --- a/libs/renderengine/gl/GLESRenderEngine.h +++ b/libs/renderengine/gl/GLESRenderEngine.h @@ -60,14 +60,16 @@ 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 std::shared_ptr<ExternalTexture>& buffer, - const bool useFramebufferCache, base::unique_fd&& bufferFence, - base::unique_fd* drawFence) override; + const sp<GraphicBuffer>& 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; } @@ -103,9 +105,6 @@ 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; diff --git a/libs/renderengine/include/renderengine/ExternalTexture.h b/libs/renderengine/include/renderengine/ExternalTexture.h deleted file mode 100644 index 07f0833d4a..0000000000 --- a/libs/renderengine/include/renderengine/ExternalTexture.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h index c54c5ba047..7661233967 100644 --- a/libs/renderengine/include/renderengine/LayerSettings.h +++ b/libs/renderengine/include/renderengine/LayerSettings.h @@ -16,9 +16,11 @@ #pragma once +#include <iosfwd> + #include <math/mat4.h> #include <math/vec3.h> -#include <renderengine/ExternalTexture.h> +#include <renderengine/Texture.h> #include <ui/BlurRegion.h> #include <ui/Fence.h> #include <ui/FloatRect.h> @@ -29,8 +31,6 @@ #include <ui/StretchEffect.h> #include <ui/Transform.h> -#include <iosfwd> - namespace android { namespace renderengine { @@ -39,7 +39,7 @@ struct Buffer { // Buffer containing the image that we will render. // If buffer == nullptr, then the rest of the fields in this struct will be // ignored. - std::shared_ptr<ExternalTexture> buffer = nullptr; + sp<GraphicBuffer> buffer = nullptr; // Fence that will fire when the buffer is ready to be bound. sp<Fence> fence = nullptr; diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h index c8a0f0a034..8dd98c3ba3 100644 --- a/libs/renderengine/include/renderengine/RenderEngine.h +++ b/libs/renderengine/include/renderengine/RenderEngine.h @@ -17,20 +17,19 @@ #ifndef SF_RENDERENGINE_H_ #define SF_RENDERENGINE_H_ +#include <stdint.h> +#include <sys/types.h> +#include <memory> + #include <android-base/unique_fd.h> #include <math/mat4.h> #include <renderengine/DisplaySettings.h> -#include <renderengine/ExternalTexture.h> #include <renderengine/Framebuffer.h> #include <renderengine/Image.h> #include <renderengine/LayerSettings.h> -#include <stdint.h> -#include <sys/types.h> #include <ui/GraphicTypes.h> #include <ui/Transform.h> -#include <memory> - /** * Allows to set RenderEngine backend to GLES (default) or SkiaGL (NOT yet supported). */ @@ -52,7 +51,6 @@ class Region; namespace renderengine { -class ExternalTexture; class Image; class Mesh; class Texture; @@ -106,6 +104,23 @@ public: virtual void genTextures(size_t count, uint32_t* names) = 0; virtual void deleteTextures(size_t count, uint32_t const* names) = 0; + // Caches Image resources for this buffer, but does not bind the buffer to + // a particular texture. + // Note that work is deferred to an additional thread, i.e. this call + // is made asynchronously, but the caller can expect that cache/unbind calls + // are performed in a manner that's conflict serializable, i.e. unbinding + // a buffer should never occur before binding the buffer if the caller + // called {bind, cache}ExternalTextureBuffer before calling unbind. + virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0; + // Removes internal resources referenced by the bufferId. This method should be + // invoked when the caller will no longer hold a reference to a GraphicBuffer + // and needs to clean up its resources. + // Note that work is deferred to an additional thread, i.e. this call + // is made asynchronously, but the caller can expect that cache/unbind calls + // are performed in a manner that's conflict serializable, i.e. unbinding + // a buffer should never occur before binding the buffer if the caller + // called {bind, cache}ExternalTextureBuffer before calling unbind. + virtual void unbindExternalTextureBuffer(uint64_t bufferId) = 0; enum class CleanupMode { CLEAN_OUTPUT_RESOURCES, @@ -176,9 +191,8 @@ public: // now, this always returns NO_ERROR. virtual status_t drawLayers(const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, - const std::shared_ptr<ExternalTexture>& buffer, - const bool useFramebufferCache, base::unique_fd&& bufferFence, - base::unique_fd* drawFence) = 0; + const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, + base::unique_fd&& bufferFence, base::unique_fd* drawFence) = 0; virtual void cleanFramebufferCache() = 0; // Returns the priority this context was actually created with. Note: this may not be // the same as specified at context creation time, due to implementation limits on the @@ -199,31 +213,6 @@ public: static void validateOutputBufferUsage(const sp<GraphicBuffer>&); protected: - // Maps GPU resources for this buffer. - // Note that work may be deferred to an additional thread, i.e. this call - // is made asynchronously, but the caller can expect that map/unmap calls - // are performed in a manner that's conflict serializable, i.e. unmapping - // a buffer should never occur before binding the buffer if the caller - // called mapExternalTextureBuffer before calling unmap. - // Note also that if the buffer contains protected content, then mapping those GPU resources may - // be deferred until the buffer is really used for drawing. This is because typical SoCs that - // support protected memory only support a limited amount, so optimisitically mapping protected - // memory may be too burdensome. If a buffer contains protected content and the RenderEngine - // implementation supports protected context, then GPU resources may be mapped into both the - // protected and unprotected contexts. - // If the buffer may ever be written to by RenderEngine, then isRenderable must be true. - virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) = 0; - // Unmaps GPU resources used by this buffer. This method should be - // invoked when the caller will no longer hold a reference to a GraphicBuffer - // and needs to clean up its resources. - // Note that if there are multiple callers holding onto the same buffer, then the buffer's - // resources may be internally ref-counted to guard against use-after-free errors. Note that - // work may be deferred to an additional thread, i.e. this call is expected to be made - // asynchronously, but the caller can expect that map/unmap calls are performed in a manner - // that's conflict serializable, i.e. unmap a buffer should never occur before binding the - // buffer if the caller called mapExternalTextureBuffer before calling unmap. - virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) = 0; - friend class ExternalTexture; friend class threaded::RenderEngineThreaded; const RenderEngineType mRenderEngineType; }; diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h index 27dbd1ecf3..228553d643 100644 --- a/libs/renderengine/include/renderengine/mock/RenderEngine.h +++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h @@ -39,6 +39,8 @@ public: MOCK_METHOD1(dump, void(std::string&)); MOCK_METHOD2(genTextures, void(size_t, uint32_t*)); MOCK_METHOD2(deleteTextures, void(size_t, uint32_t const*)); + MOCK_METHOD1(cacheExternalTextureBuffer, void(const sp<GraphicBuffer>&)); + MOCK_METHOD1(unbindExternalTextureBuffer, void(uint64_t)); MOCK_METHOD1(drawMesh, void(const renderengine::Mesh&)); MOCK_CONST_METHOD0(getMaxTextureSize, size_t()); MOCK_CONST_METHOD0(getMaxViewportDims, size_t()); @@ -48,17 +50,12 @@ public: MOCK_METHOD1(cleanupPostRender, bool(CleanupMode mode)); MOCK_METHOD6(drawLayers, status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&, - const std::shared_ptr<ExternalTexture>&, const bool, base::unique_fd&&, + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, base::unique_fd*)); MOCK_METHOD0(cleanFramebufferCache, void()); MOCK_METHOD0(getContextPriority, int()); MOCK_METHOD0(supportsBackgroundBlur, bool()); MOCK_METHOD1(onPrimaryDisplaySizeChanged, void(ui::Size)); - -protected: - // mock renderengine still needs to implement these, but callers should never need to call them. - void mapExternalTextureBuffer(const sp<GraphicBuffer>&, bool) {} - void unmapExternalTextureBuffer(const sp<GraphicBuffer>&) {} }; } // namespace mock diff --git a/libs/renderengine/skia/AutoBackendTexture.h b/libs/renderengine/skia/AutoBackendTexture.h index 2d61cf854b..bb758780e1 100644 --- a/libs/renderengine/skia/AutoBackendTexture.h +++ b/libs/renderengine/skia/AutoBackendTexture.h @@ -21,9 +21,9 @@ #include <SkImage.h> #include <SkSurface.h> #include <sys/types.h> -#include <ui/GraphicTypes.h> #include "android-base/macros.h" +#include "ui/GraphicTypes.h" namespace android { namespace renderengine { @@ -41,18 +41,13 @@ public: // of shared ownership with Skia objects, so we wrap it here instead. class LocalRef { public: - LocalRef(AutoBackendTexture* texture) { setTexture(texture); } + LocalRef() {} ~LocalRef() { // Destroying the texture is the same as setting it to null setTexture(nullptr); } - AutoBackendTexture* getTexture() const { return mTexture; } - - DISALLOW_COPY_AND_ASSIGN(LocalRef); - - private: // Sets the texture to locally ref-track. void setTexture(AutoBackendTexture* texture) { if (mTexture != nullptr) { @@ -64,6 +59,12 @@ public: mTexture->ref(); } } + + AutoBackendTexture* getTexture() const { return mTexture; } + + DISALLOW_COPY_AND_ASSIGN(LocalRef); + + private: AutoBackendTexture* mTexture = nullptr; }; diff --git a/libs/renderengine/skia/Cache.cpp b/libs/renderengine/skia/Cache.cpp index 1c2b2fc3ca..1db20c0be0 100644 --- a/libs/renderengine/skia/Cache.cpp +++ b/libs/renderengine/skia/Cache.cpp @@ -46,7 +46,7 @@ constexpr auto kDestDataSpace = ui::Dataspace::SRGB; } // namespace static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, - const std::shared_ptr<ExternalTexture>& dstTexture) { + sp<GraphicBuffer> dstBuffer) { // Somewhat arbitrary dimensions, but on screen and slightly shorter, based // on actual use. FloatRect rect(0, 0, display.physicalDisplay.width(), display.physicalDisplay.height() - 30); @@ -73,7 +73,7 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin auto layers = std::vector<const LayerSettings*>{&layer}; // The identity matrix will generate the fast shader - renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, base::unique_fd(), + renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache, base::unique_fd(), nullptr); // This matrix, which has different scales for x and y, will // generate the slower (more general case) version, which has variants for translucent @@ -86,14 +86,13 @@ static void drawShadowLayers(SkiaRenderEngine* renderengine, const DisplaySettin // clang-format on for (auto translucent : {false, true}) { layer.shadow.casterIsTranslucent = translucent; - renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, + renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache, base::unique_fd(), nullptr); } } static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, - const std::shared_ptr<ExternalTexture>& dstTexture, - const std::shared_ptr<ExternalTexture>& srcTexture) { + sp<GraphicBuffer> dstBuffer, sp<GraphicBuffer> srcBuffer) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ @@ -104,7 +103,7 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting }, .source = PixelSource{.buffer = Buffer{ - .buffer = srcTexture, + .buffer = srcBuffer, .maxMasteringLuminance = 1000.f, .maxContentLuminance = 1000.f, }}, @@ -127,7 +126,7 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting layer.source.buffer.isOpaque = isOpaque; for (auto alpha : {half(.23999f), half(1.0f)}) { layer.alpha = alpha; - renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, + renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache, base::unique_fd(), nullptr); } } @@ -136,7 +135,7 @@ static void drawImageLayers(SkiaRenderEngine* renderengine, const DisplaySetting } static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, - const std::shared_ptr<ExternalTexture>& dstTexture) { + sp<GraphicBuffer> dstBuffer) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ @@ -144,11 +143,11 @@ static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySetting Geometry{ .boundaries = rect, }, + .alpha = 1, .source = PixelSource{ .solidColor = half3(0.1f, 0.2f, 0.3f), }, - .alpha = 1, }; auto layers = std::vector<const LayerSettings*>{&layer}; @@ -156,14 +155,14 @@ static void drawSolidLayers(SkiaRenderEngine* renderengine, const DisplaySetting layer.geometry.positionTransform = transform; for (float roundedCornersRadius : {0.0f, 0.05f, 50.f}) { layer.geometry.roundedCornersRadius = roundedCornersRadius; - renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, + renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache, base::unique_fd(), nullptr); } } } static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings& display, - const std::shared_ptr<ExternalTexture>& dstTexture) { + sp<GraphicBuffer> dstBuffer) { const Rect& displayRect = display.physicalDisplay; FloatRect rect(0, 0, displayRect.width(), displayRect.height()); LayerSettings layer{ @@ -177,7 +176,7 @@ static void drawBlurLayers(SkiaRenderEngine* renderengine, const DisplaySettings auto layers = std::vector<const LayerSettings*>{&layer}; for (int radius : {9, 60}) { layer.backgroundBlurRadius = radius; - renderengine->drawLayers(display, layers, dstTexture, kUseFrameBufferCache, + renderengine->drawLayers(display, layers, dstBuffer, kUseFrameBufferCache, base::unique_fd(), nullptr); } } @@ -215,9 +214,6 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { sp<GraphicBuffer> dstBuffer = new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1, usage, "primeShaderCache_dst"); - - const auto dstTexture = std::make_shared<ExternalTexture>(dstBuffer, *renderengine, - ExternalTexture::Usage::WRITEABLE); // This buffer will be the source for the call to drawImageLayers. Draw // something to it as a placeholder for what an app draws. We should draw // something, but the details are not important. Make use of the shadow layer drawing step @@ -226,16 +222,11 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1, usage, "drawImageLayer_src"); - const auto srcTexture = - std::make_shared<ExternalTexture>(srcBuffer, *renderengine, - ExternalTexture::Usage::READABLE | - ExternalTexture::Usage::WRITEABLE); - - drawSolidLayers(renderengine, display, dstTexture); - drawShadowLayers(renderengine, display, srcTexture); - drawBlurLayers(renderengine, display, dstTexture); + drawSolidLayers(renderengine, display, dstBuffer); + drawShadowLayers(renderengine, display, srcBuffer); + drawBlurLayers(renderengine, display, dstBuffer); // The majority of shaders are related to sampling images. - drawImageLayers(renderengine, display, dstTexture, srcTexture); + drawImageLayers(renderengine, display, dstBuffer, srcBuffer); // should be the same as AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE; const int64_t usageExternal = GRALLOC_USAGE_HW_TEXTURE; @@ -243,12 +234,12 @@ void Cache::primeShaderCache(SkiaRenderEngine* renderengine) { sp<GraphicBuffer> externalBuffer = new GraphicBuffer(displayRect.width(), displayRect.height(), PIXEL_FORMAT_RGBA_8888, 1, usageExternal, "primeShaderCache_external"); - const auto externalTexture = - std::make_shared<ExternalTexture>(externalBuffer, *renderengine, - ExternalTexture::Usage::READABLE); // TODO(b/184665179) doubles number of image shader compilations, but only somewhere // between 6 and 8 will occur in real uses. - drawImageLayers(renderengine, display, dstTexture, externalTexture); + drawImageLayers(renderengine, display, dstBuffer, externalBuffer); + renderengine->unbindExternalTextureBuffer(externalBuffer->getId()); + + renderengine->unbindExternalTextureBuffer(srcBuffer->getId()); const nsecs_t timeAfter = systemTime(); const float compileTimeMs = static_cast<float>(timeAfter - timeBefore) / 1.0E6; diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp index e781584a9b..3b2c7e5f66 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp +++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp @@ -329,6 +329,8 @@ SkiaGLRenderEngine::SkiaGLRenderEngine(const RenderEngineCreationArgs& args, EGL } SkiaGLRenderEngine::~SkiaGLRenderEngine() { + cleanFramebufferCache(); + std::lock_guard<std::mutex> lock(mRenderingMutex); if (mBlurFilter) { delete mBlurFilter; @@ -482,8 +484,7 @@ static bool needsToneMapping(ui::Dataspace sourceDataspace, ui::Dataspace destin sourceTransfer != destTransfer; } -void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, - bool isRenderable) { +void SkiaGLRenderEngine::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) { // Only run this if RE is running on its own thread. This way the access to GL // operations is guaranteed to be happening on the same thread. if (mRenderEngineType != RenderEngineType::SKIA_GL_THREADED) { @@ -504,41 +505,25 @@ void SkiaGLRenderEngine::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffe auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache; std::lock_guard<std::mutex> lock(mRenderingMutex); - mGraphicBufferExternalRefs[buffer->getId()]++; - - if (const auto& iter = cache.find(buffer->getId()); iter == cache.end()) { + auto iter = cache.find(buffer->getId()); + if (iter != cache.end()) { + ALOGV("Texture already exists in cache."); + } else { std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = - std::make_shared<AutoBackendTexture::LocalRef>( - new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), - isRenderable)); + std::make_shared<AutoBackendTexture::LocalRef>(); + imageTextureRef->setTexture( + new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), false)); cache.insert({buffer->getId(), imageTextureRef}); } // restore the original state of the protected context if necessary useProtectedContext(protectedContextState); } -void SkiaGLRenderEngine::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) { +void SkiaGLRenderEngine::unbindExternalTextureBuffer(uint64_t bufferId) { ATRACE_CALL(); std::lock_guard<std::mutex> lock(mRenderingMutex); - if (const auto& iter = mGraphicBufferExternalRefs.find(buffer->getId()); - iter != mGraphicBufferExternalRefs.end()) { - if (iter->second == 0) { - ALOGW("Attempted to unmap GraphicBuffer <id: %" PRId64 - "> from RenderEngine texture, but the " - "ref count was already zero!", - buffer->getId()); - mGraphicBufferExternalRefs.erase(buffer->getId()); - return; - } - - iter->second--; - - if (iter->second == 0) { - mTextureCache.erase(buffer->getId()); - mProtectedTextureCache.erase(buffer->getId()); - mGraphicBufferExternalRefs.erase(buffer->getId()); - } - } + mTextureCache.erase(bufferId); + mProtectedTextureCache.erase(bufferId); } sk_sp<SkShader> SkiaGLRenderEngine::createRuntimeEffectShader(sk_sp<SkShader> shader, @@ -636,8 +621,8 @@ private: status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, - const std::shared_ptr<ExternalTexture>& buffer, - const bool /*useFramebufferCache*/, + const sp<GraphicBuffer>& buffer, + const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) { ATRACE_NAME("SkiaGL::drawLayers"); @@ -660,18 +645,32 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, return BAD_VALUE; } - validateOutputBufferUsage(buffer->getBuffer()); + validateOutputBufferUsage(buffer); auto grContext = mInProtectedContext ? mProtectedGrContext : mGrContext; auto& cache = mInProtectedContext ? mProtectedTextureCache : mTextureCache; + AHardwareBuffer_Desc bufferDesc; + AHardwareBuffer_describe(buffer->toAHardwareBuffer(), &bufferDesc); + + std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef = nullptr; + if (useFramebufferCache) { + auto iter = cache.find(buffer->getId()); + if (iter != cache.end()) { + ALOGV("Cache hit!"); + ATRACE_NAME("Cache hit"); + surfaceTextureRef = iter->second; + } + } - std::shared_ptr<AutoBackendTexture::LocalRef> surfaceTextureRef; - 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)); + if (surfaceTextureRef == nullptr || surfaceTextureRef->getTexture() == nullptr) { + ATRACE_NAME("Cache miss"); + surfaceTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(); + surfaceTextureRef->setTexture( + new AutoBackendTexture(grContext.get(), buffer->toAHardwareBuffer(), true)); + if (useFramebufferCache) { + ALOGD("Adding to cache"); + cache.insert({buffer->getId(), surfaceTextureRef}); + } } const ui::Dataspace dstDataspace = @@ -877,22 +876,18 @@ status_t SkiaGLRenderEngine::drawLayers(const DisplaySettings& display, SkPaint paint; if (layer->source.buffer.buffer) { ATRACE_NAME("DrawImage"); - validateInputBufferUsage(layer->source.buffer.buffer->getBuffer()); + validateInputBufferUsage(layer->source.buffer.buffer); const auto& item = layer->source.buffer; std::shared_ptr<AutoBackendTexture::LocalRef> imageTextureRef = nullptr; - - if (const auto& iter = cache.find(item.buffer->getBuffer()->getId()); - iter != cache.end()) { + auto iter = cache.find(item.buffer->getId()); + if (iter != cache.end()) { imageTextureRef = iter->second; } else { - // If we didn't find the image in the cache, then create a local ref but don't cache - // 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(), - item.buffer->getBuffer()->toAHardwareBuffer(), - false)); + imageTextureRef = std::make_shared<AutoBackendTexture::LocalRef>(); + imageTextureRef->setTexture(new AutoBackendTexture(grContext.get(), + item.buffer->toAHardwareBuffer(), + false)); + cache.insert({item.buffer->getId(), imageTextureRef}); } sk_sp<SkImage> image = @@ -1205,6 +1200,15 @@ EGLSurface SkiaGLRenderEngine::createPlaceholderEglPbufferSurface(EGLDisplay dis return eglCreatePbufferSurface(display, placeholderConfig, attributes.data()); } +void SkiaGLRenderEngine::cleanFramebufferCache() { + // TODO(b/180767535) Remove this method and use b/180767535 instead, which would allow + // SF to control texture lifecycle more tightly rather than through custom hooks into RE. + std::lock_guard<std::mutex> lock(mRenderingMutex); + mRuntimeEffects.clear(); + mProtectedTextureCache.clear(); + mTextureCache.clear(); +} + int SkiaGLRenderEngine::getContextPriority() { int value; eglQueryContext(mEGLDisplay, mEGLContext, EGL_CONTEXT_PRIORITY_LEVEL_IMG, &value); @@ -1277,12 +1281,6 @@ void SkiaGLRenderEngine::dump(std::string& result) { StringAppendF(&result, "Skia's Wrapped Objects:\n"); gpuReporter.logOutput(result, true); - StringAppendF(&result, "RenderEngine tracked buffers: %zu\n", - mGraphicBufferExternalRefs.size()); - StringAppendF(&result, "Dumping buffer ids...\n"); - for (const auto& [id, refCounts] : mGraphicBufferExternalRefs) { - StringAppendF(&result, "- 0x%" PRIx64 " - %d refs \n", id, refCounts); - } StringAppendF(&result, "RenderEngine AHB/BackendTexture cache size: %zu\n", mTextureCache.size()); StringAppendF(&result, "Dumping buffer ids...\n"); diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h index e71c560a1f..8e77c16b40 100644 --- a/libs/renderengine/skia/SkiaGLRenderEngine.h +++ b/libs/renderengine/skia/SkiaGLRenderEngine.h @@ -23,7 +23,6 @@ #include <GrDirectContext.h> #include <SkSurface.h> #include <android-base/thread_annotations.h> -#include <renderengine/ExternalTexture.h> #include <renderengine/RenderEngine.h> #include <sys/types.h> @@ -53,12 +52,13 @@ public: ~SkiaGLRenderEngine() override EXCLUDES(mRenderingMutex); void primeCache() override; + void cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override; + void unbindExternalTextureBuffer(uint64_t bufferId) override; status_t drawLayers(const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, - const std::shared_ptr<ExternalTexture>& buffer, - const bool useFramebufferCache, base::unique_fd&& bufferFence, - base::unique_fd* drawFence) override; - void cleanFramebufferCache() override {} + const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, + base::unique_fd&& bufferFence, base::unique_fd* drawFence) override; + void cleanFramebufferCache() override; int getContextPriority() override; bool isProtected() const override { return mInProtectedContext; } bool supportsProtectedContent() const override; @@ -72,8 +72,6 @@ protected: void dump(std::string& result) override; size_t getMaxTextureSize() const override; size_t getMaxViewportDims() const override; - void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override; - void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override; private: static EGLConfig chooseEglConfig(EGLDisplay display, int format, bool logConfig); @@ -116,9 +114,7 @@ private: const PixelFormat mDefaultPixelFormat; const bool mUseColorManagement; - // Number of external holders of ExternalTexture references, per GraphicBuffer ID. - std::unordered_map<uint64_t, int32_t> mGraphicBufferExternalRefs GUARDED_BY(mRenderingMutex); - // Cache of GL textures that we'll store per GraphicBuffer ID, sliced by GPU context. + // Cache of GL textures that we'll store per GraphicBuffer ID std::unordered_map<uint64_t, std::shared_ptr<AutoBackendTexture::LocalRef>> mTextureCache GUARDED_BY(mRenderingMutex); std::unordered_map<uint64_t, std::shared_ptr<AutoBackendTexture::LocalRef>> diff --git a/libs/renderengine/skia/SkiaRenderEngine.h b/libs/renderengine/skia/SkiaRenderEngine.h index 308c5ffa9f..51ef088a25 100644 --- a/libs/renderengine/skia/SkiaRenderEngine.h +++ b/libs/renderengine/skia/SkiaRenderEngine.h @@ -42,12 +42,15 @@ public: virtual void primeCache() override{}; virtual void genTextures(size_t /*count*/, uint32_t* /*names*/) override{}; virtual void deleteTextures(size_t /*count*/, uint32_t const* /*names*/) override{}; + virtual void cacheExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/){}; + virtual void unbindExternalTextureBuffer(uint64_t /*bufferId*/){}; + virtual bool isProtected() const override { return false; } // mInProtectedContext; } virtual bool supportsProtectedContent() const override { return false; }; virtual bool useProtectedContext(bool /*useProtectedContext*/) override { return false; }; virtual status_t drawLayers(const DisplaySettings& /*display*/, const std::vector<const LayerSettings*>& /*layers*/, - const std::shared_ptr<ExternalTexture>& /*buffer*/, + const sp<GraphicBuffer>& /*buffer*/, const bool /*useFramebufferCache*/, base::unique_fd&& /*bufferFence*/, base::unique_fd* /*drawFence*/) override { @@ -57,11 +60,6 @@ public: virtual int getContextPriority() override { return 0; } virtual void assertShadersCompiled(int numShaders) {} virtual int reportShadersCompiled() { return 0; } - -protected: - virtual void mapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/, - bool /*isRenderable*/) override; - virtual void unmapExternalTextureBuffer(const sp<GraphicBuffer>& /*buffer*/) override; }; } // namespace skia diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp index d63c88bc02..7846156383 100644 --- a/libs/renderengine/tests/RenderEngineTest.cpp +++ b/libs/renderengine/tests/RenderEngineTest.cpp @@ -24,7 +24,6 @@ #include <cutils/properties.h> #include <gtest/gtest.h> -#include <renderengine/ExternalTexture.h> #include <renderengine/RenderEngine.h> #include <sync/sync.h> #include <ui/PixelFormat.h> @@ -161,42 +160,27 @@ public: class RenderEngineTest : public ::testing::TestWithParam<std::shared_ptr<RenderEngineFactory>> { public: - std::shared_ptr<renderengine::ExternalTexture> allocateDefaultBuffer() { - return std::make_shared< - renderengine:: - ExternalTexture>(new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, - DEFAULT_DISPLAY_HEIGHT, - HAL_PIXEL_FORMAT_RGBA_8888, 1, - GRALLOC_USAGE_SW_READ_OFTEN | - GRALLOC_USAGE_SW_WRITE_OFTEN | - GRALLOC_USAGE_HW_RENDER | - GRALLOC_USAGE_HW_TEXTURE, - "output"), - *mRE, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage::WRITEABLE); + static sp<GraphicBuffer> allocateDefaultBuffer() { + return new GraphicBuffer(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT, + HAL_PIXEL_FORMAT_RGBA_8888, 1, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | + GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE, + "output"); } // Allocates a 1x1 buffer to fill with a solid color - std::shared_ptr<renderengine::ExternalTexture> allocateSourceBuffer(uint32_t width, - uint32_t height) { - return std::make_shared< - renderengine:: - ExternalTexture>(new GraphicBuffer(width, height, - HAL_PIXEL_FORMAT_RGBA_8888, 1, - GRALLOC_USAGE_SW_READ_OFTEN | - GRALLOC_USAGE_SW_WRITE_OFTEN | - GRALLOC_USAGE_HW_TEXTURE, - "input"), - *mRE, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage::WRITEABLE); + static sp<GraphicBuffer> allocateSourceBuffer(uint32_t width, uint32_t height) { + return new GraphicBuffer(width, height, HAL_PIXEL_FORMAT_RGBA_8888, 1, + GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | + GRALLOC_USAGE_HW_TEXTURE, + "input"); } RenderEngineTest() { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); + mBuffer = allocateDefaultBuffer(); } ~RenderEngineTest() { @@ -227,21 +211,20 @@ public: } uint8_t* pixels; - mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - reinterpret_cast<void**>(&pixels)); + mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); file << "P6\n"; - file << mBuffer->getBuffer()->getWidth() << "\n"; - file << mBuffer->getBuffer()->getHeight() << "\n"; + file << mBuffer->getWidth() << "\n"; + file << mBuffer->getHeight() << "\n"; file << 255 << "\n"; - std::vector<uint8_t> outBuffer(mBuffer->getBuffer()->getWidth() * - mBuffer->getBuffer()->getHeight() * 3); + std::vector<uint8_t> outBuffer(mBuffer->getWidth() * mBuffer->getHeight() * 3); auto outPtr = reinterpret_cast<uint8_t*>(outBuffer.data()); - for (int32_t j = 0; j < mBuffer->getBuffer()->getHeight(); j++) { - const uint8_t* src = pixels + (mBuffer->getBuffer()->getStride() * j) * 4; - for (int32_t i = 0; i < mBuffer->getBuffer()->getWidth(); i++) { + for (int32_t j = 0; j < mBuffer->getHeight(); j++) { + const uint8_t* src = pixels + (mBuffer->getStride() * j) * 4; + for (int32_t i = 0; i < mBuffer->getWidth(); i++) { // Only copy R, G and B components outPtr[0] = src[0]; outPtr[1] = src[1]; @@ -252,7 +235,7 @@ public: } } file.write(reinterpret_cast<char*>(outBuffer.data()), outBuffer.size()); - mBuffer->getBuffer()->unlock(); + mBuffer->unlock(); } void expectBufferColor(const Region& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { @@ -279,13 +262,13 @@ public: void expectBufferColor(const Rect& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a, std::function<bool(const uint8_t* a, const uint8_t* b)> colorCompare) { uint8_t* pixels; - mBuffer->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - reinterpret_cast<void**>(&pixels)); + mBuffer->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); int32_t maxFails = 10; int32_t fails = 0; for (int32_t j = 0; j < region.getHeight(); j++) { - const uint8_t* src = pixels + - (mBuffer->getBuffer()->getStride() * (region.top + j) + region.left) * 4; + const uint8_t* src = + pixels + (mBuffer->getStride() * (region.top + j) + region.left) * 4; for (int32_t i = 0; i < region.getWidth(); i++) { const uint8_t expected[4] = {r, g, b, a}; bool equal = colorCompare(src, expected); @@ -306,7 +289,7 @@ public: break; } } - mBuffer->getBuffer()->unlock(); + mBuffer->unlock(); } void expectAlpha(const Rect& rect, uint8_t a) { @@ -404,6 +387,7 @@ public: base::unique_fd fence; status_t status = mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), &fence); + mCurrentBuffer = mBuffer; int fd = fence.release(); if (fd >= 0) { @@ -413,7 +397,7 @@ public: ASSERT_EQ(NO_ERROR, status); if (layers.size() > 0 && mGLESRE != nullptr) { - ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId())); + ASSERT_TRUE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId())); } } @@ -519,11 +503,17 @@ public: void initializeRenderEngine(); std::unique_ptr<renderengine::RenderEngine> mRE; - std::shared_ptr<renderengine::ExternalTexture> mBuffer; // GLESRenderEngine for testing GLES-specific behavior. // Owened by mRE, but this is downcasted. renderengine::gl::GLESRenderEngine* mGLESRE = nullptr; + // Dumb hack to avoid NPE in the EGL driver: the GraphicBuffer needs to + // be freed *after* RenderEngine is destroyed, so that the EGL image is + // destroyed first. + sp<GraphicBuffer> mCurrentBuffer; + + sp<GraphicBuffer> mBuffer; + std::vector<uint32_t> mTexNames; }; @@ -540,7 +530,6 @@ void RenderEngineTest::initializeRenderEngine() { } else { mRE = renderEngineFactory->createRenderEngine(); } - mBuffer = allocateDefaultBuffer(); } struct ColorSourceVariant { @@ -577,18 +566,18 @@ template <typename OpaquenessVariant> struct BufferSourceVariant { static void fillColor(renderengine::LayerSettings& layer, half r, half g, half b, RenderEngineTest* fixture) { - const auto buf = fixture->allocateSourceBuffer(1, 1); + sp<GraphicBuffer> buf = RenderEngineTest::allocateSourceBuffer(1, 1); uint32_t texName; fixture->mRE->genTextures(1, &texName); fixture->mTexNames.push_back(texName); uint8_t* pixels; - buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - reinterpret_cast<void**>(&pixels)); + buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); - for (int32_t j = 0; j < buf->getBuffer()->getHeight(); j++) { - uint8_t* iter = pixels + (buf->getBuffer()->getStride() * j) * 4; - for (int32_t i = 0; i < buf->getBuffer()->getWidth(); i++) { + for (int32_t j = 0; j < buf->getHeight(); j++) { + uint8_t* iter = pixels + (buf->getStride() * j) * 4; + for (int32_t i = 0; i < buf->getWidth(); i++) { iter[0] = uint8_t(r * 255); iter[1] = uint8_t(g * 255); iter[2] = uint8_t(b * 255); @@ -597,7 +586,7 @@ struct BufferSourceVariant { } } - buf->getBuffer()->unlock(); + buf->unlock(); layer.source.buffer.buffer = buf; layer.source.buffer.textureName = texName; @@ -1023,14 +1012,14 @@ void RenderEngineTest::fillRedBufferTextureTransform() { layer.sourceDataspace = ui::Dataspace::V0_SRGB_LINEAR; // Here will allocate a checker board texture, but transform texture // coordinates so that only the upper left is applied. - const auto buf = allocateSourceBuffer(2, 2); + sp<GraphicBuffer> buf = allocateSourceBuffer(2, 2); uint32_t texName; RenderEngineTest::mRE->genTextures(1, &texName); this->mTexNames.push_back(texName); uint8_t* pixels; - buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - reinterpret_cast<void**>(&pixels)); + buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); // Red top left, Green top right, Blue bottom left, Black bottom right pixels[0] = 255; pixels[1] = 0; @@ -1044,7 +1033,7 @@ void RenderEngineTest::fillRedBufferTextureTransform() { pixels[9] = 0; pixels[10] = 255; pixels[11] = 255; - buf->getBuffer()->unlock(); + buf->unlock(); layer.source.buffer.buffer = buf; layer.source.buffer.textureName = texName; @@ -1072,19 +1061,19 @@ void RenderEngineTest::fillRedBufferWithPremultiplyAlpha() { std::vector<const renderengine::LayerSettings*> layers; renderengine::LayerSettings layer; - const auto buf = allocateSourceBuffer(1, 1); + sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1); uint32_t texName; RenderEngineTest::mRE->genTextures(1, &texName); this->mTexNames.push_back(texName); uint8_t* pixels; - buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - reinterpret_cast<void**>(&pixels)); + buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); pixels[0] = 255; pixels[1] = 0; pixels[2] = 0; pixels[3] = 255; - buf->getBuffer()->unlock(); + buf->unlock(); layer.source.buffer.buffer = buf; layer.source.buffer.textureName = texName; @@ -1111,19 +1100,19 @@ void RenderEngineTest::fillRedBufferWithoutPremultiplyAlpha() { std::vector<const renderengine::LayerSettings*> layers; renderengine::LayerSettings layer; - const auto buf = allocateSourceBuffer(1, 1); + sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1); uint32_t texName; RenderEngineTest::mRE->genTextures(1, &texName); this->mTexNames.push_back(texName); uint8_t* pixels; - buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - reinterpret_cast<void**>(&pixels)); + buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); pixels[0] = 255; pixels[1] = 0; pixels[2] = 0; pixels[3] = 255; - buf->getBuffer()->unlock(); + buf->unlock(); layer.source.buffer.buffer = buf; layer.source.buffer.textureName = texName; @@ -1244,7 +1233,8 @@ TEST_P(RenderEngineTest, drawLayers_noLayersToDraw) { } TEST_P(RenderEngineTest, drawLayers_withoutBuffers_withColorTransform) { - initializeRenderEngine(); + const auto& renderEngineFactory = GetParam(); + mRE = renderEngineFactory->createRenderEngine(); renderengine::DisplaySettings settings; settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; @@ -1305,6 +1295,7 @@ TEST_P(RenderEngineTest, drawLayers_nullOutputFence) { layers.push_back(&layer); status_t status = mRE->drawLayers(settings, layers, mBuffer, true, base::unique_fd(), nullptr); + mCurrentBuffer = mBuffer; ASSERT_EQ(NO_ERROR, status); expectBufferColor(fullscreenRect(), 255, 0, 0, 255); } @@ -1332,8 +1323,9 @@ TEST_P(RenderEngineTest, drawLayers_doesNotCacheFramebuffer) { layers.push_back(&layer); status_t status = mRE->drawLayers(settings, layers, mBuffer, false, base::unique_fd(), nullptr); + mCurrentBuffer = mBuffer; ASSERT_EQ(NO_ERROR, status); - ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getBuffer()->getId())); + ASSERT_FALSE(mGLESRE->isFramebufferImageCachedForTesting(mBuffer->getId())); expectBufferColor(fullscreenRect(), 255, 0, 0, 255); } @@ -1582,6 +1574,98 @@ TEST_P(RenderEngineTest, drawLayers_clearRegion) { clearRegion(); } +TEST_P(RenderEngineTest, drawLayers_fillsBufferAndCachesImages) { + const auto& renderEngineFactory = GetParam(); + + if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { + // GLES-specific test + return; + } + + initializeRenderEngine(); + + renderengine::DisplaySettings settings; + settings.outputDataspace = ui::Dataspace::V0_SRGB_LINEAR; + settings.physicalDisplay = fullscreenRect(); + settings.clip = fullscreenRect(); + + std::vector<const renderengine::LayerSettings*> layers; + + renderengine::LayerSettings layer; + layer.geometry.boundaries = fullscreenRect().toFloatRect(); + BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this); + + layers.push_back(&layer); + invokeDraw(settings, layers); + uint64_t bufferId = layer.source.buffer.buffer->getId(); + EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId)); + std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier = + mGLESRE->unbindExternalTextureBufferForTesting(bufferId); + std::lock_guard<std::mutex> lock(barrier->mutex); + ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5), + [&]() REQUIRES(barrier->mutex) { + return barrier->isOpen; + })); + EXPECT_FALSE(mGLESRE->isImageCachedForTesting(bufferId)); + EXPECT_EQ(NO_ERROR, barrier->result); +} + +TEST_P(RenderEngineTest, cacheExternalBuffer_withNullBuffer) { + const auto& renderEngineFactory = GetParam(); + + if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { + // GLES-specific test + return; + } + + initializeRenderEngine(); + + std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier = + mGLESRE->cacheExternalTextureBufferForTesting(nullptr); + std::lock_guard<std::mutex> lock(barrier->mutex); + ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5), + [&]() REQUIRES(barrier->mutex) { + return barrier->isOpen; + })); + EXPECT_TRUE(barrier->isOpen); + EXPECT_EQ(BAD_VALUE, barrier->result); +} + +TEST_P(RenderEngineTest, cacheExternalBuffer_cachesImages) { + const auto& renderEngineFactory = GetParam(); + + if (renderEngineFactory->type() != renderengine::RenderEngine::RenderEngineType::GLES) { + // GLES-specific test + return; + } + + initializeRenderEngine(); + + sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1); + uint64_t bufferId = buf->getId(); + std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier = + mGLESRE->cacheExternalTextureBufferForTesting(buf); + { + std::lock_guard<std::mutex> lock(barrier->mutex); + ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5), + [&]() REQUIRES(barrier->mutex) { + return barrier->isOpen; + })); + EXPECT_EQ(NO_ERROR, barrier->result); + } + EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId)); + barrier = mGLESRE->unbindExternalTextureBufferForTesting(bufferId); + { + std::lock_guard<std::mutex> lock(barrier->mutex); + ASSERT_TRUE(barrier->condition.wait_for(barrier->mutex, std::chrono::seconds(5), + [&]() REQUIRES(barrier->mutex) { + return barrier->isOpen; + })); + EXPECT_EQ(NO_ERROR, barrier->result); + } + EXPECT_FALSE(mGLESRE->isImageCachedForTesting(bufferId)); +} + TEST_P(RenderEngineTest, drawLayers_fillShadow_castsWithoutCasterLayer) { initializeRenderEngine(); @@ -1774,7 +1858,7 @@ TEST_P(RenderEngineTest, cleanupPostRender_whenCleaningAll_replacesTextureMemory sync_wait(fd, -1); } - uint64_t bufferId = layer.source.buffer.buffer->getBuffer()->getId(); + uint64_t bufferId = layer.source.buffer.buffer->getId(); uint32_t texName = layer.source.buffer.textureName; EXPECT_TRUE(mGLESRE->isImageCachedForTesting(bufferId)); EXPECT_EQ(bufferId, mGLESRE->getBufferIdForTextureNameForTesting(texName)); @@ -1882,16 +1966,16 @@ TEST_P(RenderEngineTest, testDisableBlendingBuffer) { // The next layer will overwrite redLayer with a GraphicBuffer that is green // applied with a translucent alpha. - const auto buf = allocateSourceBuffer(1, 1); + auto buf = allocateSourceBuffer(1, 1); { uint8_t* pixels; - buf->getBuffer()->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, - reinterpret_cast<void**>(&pixels)); + buf->lock(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, + reinterpret_cast<void**>(&pixels)); pixels[0] = 0; pixels[1] = 255; pixels[2] = 0; pixels[3] = 255; - buf->getBuffer()->unlock(); + buf->unlock(); } const renderengine::LayerSettings greenLayer{ diff --git a/libs/renderengine/tests/RenderEngineThreadedTest.cpp b/libs/renderengine/tests/RenderEngineThreadedTest.cpp index e3917cce09..b093e88d4f 100644 --- a/libs/renderengine/tests/RenderEngineThreadedTest.cpp +++ b/libs/renderengine/tests/RenderEngineThreadedTest.cpp @@ -162,18 +162,15 @@ TEST_F(RenderEngineThreadedTest, supportsBackgroundBlur_returnsTrue) { TEST_F(RenderEngineThreadedTest, drawLayers) { renderengine::DisplaySettings settings; std::vector<const renderengine::LayerSettings*> layers; - std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(), *mRenderEngine, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage::WRITEABLE); + sp<GraphicBuffer> buffer = new GraphicBuffer(); base::unique_fd bufferFence; base::unique_fd drawFence; EXPECT_CALL(*mRenderEngine, drawLayers) .WillOnce([](const renderengine::DisplaySettings&, const std::vector<const renderengine::LayerSettings*>&, - const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd&&, base::unique_fd*) -> status_t { return NO_ERROR; }); + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { return NO_ERROR; }); status_t result = mThreadedRE->drawLayers(settings, layers, buffer, false, std::move(bufferFence), &drawFence); diff --git a/libs/renderengine/threaded/RenderEngineThreaded.cpp b/libs/renderengine/threaded/RenderEngineThreaded.cpp index c9f6296b49..194c7da1c7 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.cpp +++ b/libs/renderengine/threaded/RenderEngineThreaded.cpp @@ -157,28 +157,27 @@ void RenderEngineThreaded::deleteTextures(size_t count, uint32_t const* names) { resultFuture.wait(); } -void RenderEngineThreaded::mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, - bool isRenderable) { +void RenderEngineThreaded::cacheExternalTextureBuffer(const sp<GraphicBuffer>& buffer) { // This function is designed so it can run asynchronously, so we do not need to wait // for the futures. { std::lock_guard lock(mThreadMutex); mFunctionCalls.push([=](renderengine::RenderEngine& instance) { - ATRACE_NAME("REThreaded::mapExternalTextureBuffer"); - instance.mapExternalTextureBuffer(buffer, isRenderable); + ATRACE_NAME("REThreaded::cacheExternalTextureBuffer"); + instance.cacheExternalTextureBuffer(buffer); }); } mCondition.notify_one(); } -void RenderEngineThreaded::unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) { +void RenderEngineThreaded::unbindExternalTextureBuffer(uint64_t bufferId) { // This function is designed so it can run asynchronously, so we do not need to wait // for the futures. { std::lock_guard lock(mThreadMutex); mFunctionCalls.push([=](renderengine::RenderEngine& instance) { - ATRACE_NAME("REThreaded::unmapExternalTextureBuffer"); - instance.unmapExternalTextureBuffer(buffer); + ATRACE_NAME("REThreaded::unbindExternalTextureBuffer"); + instance.unbindExternalTextureBuffer(bufferId); }); } mCondition.notify_one(); @@ -240,7 +239,7 @@ bool RenderEngineThreaded::cleanupPostRender(CleanupMode mode) { status_t RenderEngineThreaded::drawLayers(const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, - const std::shared_ptr<ExternalTexture>& buffer, + const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence, base::unique_fd* drawFence) { diff --git a/libs/renderengine/threaded/RenderEngineThreaded.h b/libs/renderengine/threaded/RenderEngineThreaded.h index eb6098ed8d..61ae9b8cf8 100644 --- a/libs/renderengine/threaded/RenderEngineThreaded.h +++ b/libs/renderengine/threaded/RenderEngineThreaded.h @@ -48,6 +48,8 @@ public: 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) override; + void unbindExternalTextureBuffer(uint64_t bufferId) override; size_t getMaxTextureSize() const override; size_t getMaxViewportDims() const override; @@ -58,19 +60,14 @@ public: status_t drawLayers(const DisplaySettings& display, const std::vector<const LayerSettings*>& layers, - const std::shared_ptr<ExternalTexture>& buffer, - const bool useFramebufferCache, base::unique_fd&& bufferFence, - base::unique_fd* drawFence) override; + const sp<GraphicBuffer>& buffer, const bool useFramebufferCache, + base::unique_fd&& bufferFence, base::unique_fd* drawFence) override; void cleanFramebufferCache() override; int getContextPriority() override; bool supportsBackgroundBlur() override; void onPrimaryDisplaySizeChanged(ui::Size size) override; -protected: - void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, bool isRenderable) override; - void unmapExternalTextureBuffer(const sp<GraphicBuffer>& buffer) override; - private: void threadMain(CreateInstanceFactory factory); void waitUntilInitialized() const; diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 13ac7c3563..be9bce0795 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -188,7 +188,7 @@ std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareCli const bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) || (isSecure() && !targetSettings.isSecure); const bool bufferCanBeUsedAsHwTexture = - mBufferInfo.mBuffer->getBuffer()->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE; + mBufferInfo.mBuffer->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE; compositionengine::LayerFE::LayerSettings& layer = *result; if (blackOutLayer || !bufferCanBeUsedAsHwTexture) { ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable", @@ -213,7 +213,7 @@ std::optional<compositionengine::LayerFE::LayerSettings> BufferLayer::prepareCli ? mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel : defaultMaxContentLuminance; layer.frameNumber = mCurrentFrameNumber; - layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer()->getId() : 0; + layer.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getId() : 0; const bool useFiltering = targetSettings.needsFiltering || mNeedsFiltering || bufferNeedsFiltering(); @@ -314,7 +314,7 @@ void BufferLayer::preparePerFrameCompositionState() { : Hwc2::IComposerClient::Composition::DEVICE; } - compositionState->buffer = mBufferInfo.mBuffer->getBuffer(); + compositionState->buffer = mBufferInfo.mBuffer; compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT) ? 0 : mBufferInfo.mBufferSlot; @@ -442,7 +442,7 @@ bool BufferLayer::onPostComposition(const DisplayDevice* display, void BufferLayer::gatherBufferInfo() { mBufferInfo.mPixelFormat = - !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->getBuffer()->format; + !mBufferInfo.mBuffer ? PIXEL_FORMAT_NONE : mBufferInfo.mBuffer->format; mBufferInfo.mFrameLatencyNeeded = true; } @@ -544,10 +544,10 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, } if (oldBufferInfo.mBuffer != nullptr) { - uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth(); - uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight(); - if (bufWidth != uint32_t(oldBufferInfo.mBuffer->getBuffer()->width) || - bufHeight != uint32_t(oldBufferInfo.mBuffer->getBuffer()->height)) { + uint32_t bufWidth = mBufferInfo.mBuffer->getWidth(); + uint32_t bufHeight = mBufferInfo.mBuffer->getHeight(); + if (bufWidth != uint32_t(oldBufferInfo.mBuffer->width) || + bufHeight != uint32_t(oldBufferInfo.mBuffer->height)) { recomputeVisibleRegions = true; } } @@ -612,8 +612,8 @@ uint32_t BufferLayer::getEffectiveScalingMode() const { } bool BufferLayer::isProtected() const { - return (mBufferInfo.mBuffer != nullptr) && - (mBufferInfo.mBuffer->getBuffer()->getUsage() & GRALLOC_USAGE_PROTECTED); + const sp<GraphicBuffer>& buffer(mBufferInfo.mBuffer); + return (buffer != 0) && (buffer->getUsage() & GRALLOC_USAGE_PROTECTED); } // h/w composer set-up @@ -727,8 +727,8 @@ Rect BufferLayer::getBufferSize(const State& s) const { return Rect::INVALID_RECT; } - uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth(); - uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight(); + uint32_t bufWidth = mBufferInfo.mBuffer->getWidth(); + uint32_t bufHeight = mBufferInfo.mBuffer->getHeight(); // Undo any transformations on the buffer and return the result. if (mBufferInfo.mTransform & ui::Transform::ROT_90) { @@ -759,8 +759,8 @@ FloatRect BufferLayer::computeSourceBounds(const FloatRect& parentBounds) const return parentBounds; } - uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth(); - uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight(); + uint32_t bufWidth = mBufferInfo.mBuffer->getWidth(); + uint32_t bufHeight = mBufferInfo.mBuffer->getHeight(); // Undo any transformations on the buffer and return the result. if (mBufferInfo.mTransform & ui::Transform::ROT_90) { @@ -802,7 +802,7 @@ Rect BufferLayer::getBufferCrop() const { return mBufferInfo.mCrop; } else if (mBufferInfo.mBuffer != nullptr) { // otherwise we use the whole buffer - return mBufferInfo.mBuffer->getBuffer()->getBounds(); + return mBufferInfo.mBuffer->getBounds(); } else { // if we don't have a buffer yet, we use an empty/invalid crop return Rect(); @@ -847,14 +847,12 @@ ui::Dataspace BufferLayer::translateDataspace(ui::Dataspace dataspace) { } sp<GraphicBuffer> BufferLayer::getBuffer() const { - return mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() : nullptr; + return mBufferInfo.mBuffer; } void BufferLayer::getDrawingTransformMatrix(bool filteringEnabled, float outMatrix[16]) { - GLConsumer::computeTransformMatrix(outMatrix, - mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getBuffer() - : nullptr, - mBufferInfo.mCrop, mBufferInfo.mTransform, filteringEnabled); + GLConsumer::computeTransformMatrix(outMatrix, mBufferInfo.mBuffer, mBufferInfo.mCrop, + mBufferInfo.mTransform, filteringEnabled); } void BufferLayer::setInitialValuesForClone(const sp<Layer>& clonedFrom) { diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index 855324710e..b8d3f12322 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -134,7 +134,7 @@ protected: PixelFormat mPixelFormat{PIXEL_FORMAT_NONE}; bool mTransformToDisplayInverse{false}; - std::shared_ptr<renderengine::ExternalTexture> mBuffer; + sp<GraphicBuffer> mBuffer; int mBufferSlot{BufferQueue::INVALID_BUFFER_SLOT}; bool mFrameLatencyNeeded{false}; diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp index 96b22478ab..69d2d11a4d 100644 --- a/services/surfaceflinger/BufferLayerConsumer.cpp +++ b/services/surfaceflinger/BufferLayerConsumer.cpp @@ -40,6 +40,7 @@ #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> #include <private/gui/ComposerService.h> +#include <renderengine/Image.h> #include <renderengine/RenderEngine.h> #include <utils/Log.h> #include <utils/String8.h> @@ -166,7 +167,7 @@ void BufferLayerConsumer::setReleaseFence(const sp<Fence>& fence) { } auto buffer = mPendingRelease.isPending ? mPendingRelease.graphicBuffer - : mCurrentTextureBuffer->getBuffer(); + : mCurrentTextureBuffer->graphicBuffer(); auto err = addReleaseFence(slot, buffer, fence); if (err != OK) { BLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)", strerror(-err), err); @@ -205,11 +206,9 @@ status_t BufferLayerConsumer::acquireBufferLocked(BufferItem* item, nsecs_t pres // before, so we need to clean up old references. if (item->mGraphicBuffer != nullptr) { std::lock_guard<std::mutex> lock(mImagesMutex); - if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->getBuffer() == nullptr || - mImages[item->mSlot]->getBuffer()->getId() != item->mGraphicBuffer->getId()) { - mImages[item->mSlot] = std::make_shared< - renderengine::ExternalTexture>(item->mGraphicBuffer, mRE, - renderengine::ExternalTexture::Usage::READABLE); + if (mImages[item->mSlot] == nullptr || mImages[item->mSlot]->graphicBuffer() == nullptr || + mImages[item->mSlot]->graphicBuffer()->getId() != item->mGraphicBuffer->getId()) { + mImages[item->mSlot] = std::make_shared<Image>(item->mGraphicBuffer, mRE); } } @@ -223,8 +222,8 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, int slot = item.mSlot; BLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)", mCurrentTexture, - (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->getBuffer() != nullptr) - ? mCurrentTextureBuffer->getBuffer()->handle + (mCurrentTextureBuffer != nullptr && mCurrentTextureBuffer->graphicBuffer() != nullptr) + ? mCurrentTextureBuffer->graphicBuffer()->handle : 0, slot, mSlots[slot].mGraphicBuffer->handle); @@ -232,7 +231,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, // releaseBufferLocked() if we're in shared buffer mode and both buffers are // the same. - std::shared_ptr<renderengine::ExternalTexture> nextTextureBuffer; + std::shared_ptr<Image> nextTextureBuffer; { std::lock_guard<std::mutex> lock(mImagesMutex); nextTextureBuffer = mImages[slot]; @@ -242,7 +241,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) { if (pendingRelease == nullptr) { status_t status = - releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->getBuffer()); + releaseBufferLocked(mCurrentTexture, mCurrentTextureBuffer->graphicBuffer()); if (status < NO_ERROR) { BLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)", strerror(-status), status); @@ -251,7 +250,7 @@ status_t BufferLayerConsumer::updateAndReleaseLocked(const BufferItem& item, } } else { pendingRelease->currentTexture = mCurrentTexture; - pendingRelease->graphicBuffer = mCurrentTextureBuffer->getBuffer(); + pendingRelease->graphicBuffer = mCurrentTextureBuffer->graphicBuffer(); pendingRelease->isPending = true; } } @@ -302,14 +301,14 @@ void BufferLayerConsumer::setFilteringEnabled(bool enabled) { void BufferLayerConsumer::computeCurrentTransformMatrixLocked() { BLC_LOGV("computeCurrentTransformMatrixLocked"); - if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->getBuffer() == nullptr) { + if (mCurrentTextureBuffer == nullptr || mCurrentTextureBuffer->graphicBuffer() == nullptr) { BLC_LOGD("computeCurrentTransformMatrixLocked: " "mCurrentTextureBuffer is nullptr"); } GLConsumer::computeTransformMatrix(mCurrentTransformMatrix, mCurrentTextureBuffer == nullptr ? nullptr - : mCurrentTextureBuffer->getBuffer(), + : mCurrentTextureBuffer->graphicBuffer(), getCurrentCropLocked(), mCurrentTransform, mFilteringEnabled); } @@ -361,8 +360,7 @@ int BufferLayerConsumer::getCurrentApi() const { return mCurrentApi; } -std::shared_ptr<renderengine::ExternalTexture> BufferLayerConsumer::getCurrentBuffer( - int* outSlot, sp<Fence>* outFence) const { +sp<GraphicBuffer> BufferLayerConsumer::getCurrentBuffer(int* outSlot, sp<Fence>* outFence) const { Mutex::Autolock lock(mMutex); if (outSlot != nullptr) { @@ -373,7 +371,7 @@ std::shared_ptr<renderengine::ExternalTexture> BufferLayerConsumer::getCurrentBu *outFence = mCurrentFence; } - return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer; + return mCurrentTextureBuffer == nullptr ? nullptr : mCurrentTextureBuffer->graphicBuffer(); } Rect BufferLayerConsumer::getCurrentCrop() const { @@ -458,12 +456,10 @@ void BufferLayerConsumer::onSidebandStreamChanged() { void BufferLayerConsumer::onBufferAvailable(const BufferItem& item) { if (item.mGraphicBuffer != nullptr && item.mSlot != BufferQueue::INVALID_BUFFER_SLOT) { std::lock_guard<std::mutex> lock(mImagesMutex); - const std::shared_ptr<renderengine::ExternalTexture>& oldImage = mImages[item.mSlot]; - if (oldImage == nullptr || oldImage->getBuffer() == nullptr || - oldImage->getBuffer()->getId() != item.mGraphicBuffer->getId()) { - mImages[item.mSlot] = std::make_shared< - renderengine::ExternalTexture>(item.mGraphicBuffer, mRE, - renderengine::ExternalTexture::Usage::READABLE); + const std::shared_ptr<Image>& oldImage = mImages[item.mSlot]; + if (oldImage == nullptr || oldImage->graphicBuffer() == nullptr || + oldImage->graphicBuffer()->getId() != item.mGraphicBuffer->getId()) { + mImages[item.mSlot] = std::make_shared<Image>(item.mGraphicBuffer, mRE); } } } @@ -503,6 +499,22 @@ void BufferLayerConsumer::dumpLocked(String8& result, const char* prefix) const ConsumerBase::dumpLocked(result, prefix); } + +BufferLayerConsumer::Image::Image(const sp<GraphicBuffer>& graphicBuffer, + renderengine::RenderEngine& engine) + : mGraphicBuffer(graphicBuffer), mRE(engine) { + if (graphicBuffer != nullptr && (graphicBuffer->getUsage() & GRALLOC_USAGE_PROTECTED)) { + return; + } + mRE.cacheExternalTextureBuffer(mGraphicBuffer); +} + +BufferLayerConsumer::Image::~Image() { + if (mGraphicBuffer != nullptr) { + ALOGV("Destroying buffer: %" PRId64, mGraphicBuffer->getId()); + mRE.unbindExternalTextureBuffer(mGraphicBuffer->getId()); + } +} }; // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues diff --git a/services/surfaceflinger/BufferLayerConsumer.h b/services/surfaceflinger/BufferLayerConsumer.h index 9ed80b46bd..dd39214aff 100644 --- a/services/surfaceflinger/BufferLayerConsumer.h +++ b/services/surfaceflinger/BufferLayerConsumer.h @@ -21,11 +21,12 @@ #include <gui/BufferQueueDefs.h> #include <gui/ConsumerBase.h> #include <gui/HdrMetadata.h> -#include <renderengine/ExternalTexture.h> + #include <ui/FenceTime.h> #include <ui/GraphicBuffer.h> #include <ui/GraphicTypes.h> #include <ui/Region.h> + #include <utils/String8.h> #include <utils/Vector.h> #include <utils/threads.h> @@ -38,6 +39,7 @@ class String8; namespace renderengine { class RenderEngine; +class Image; } // namespace renderengine /* @@ -151,8 +153,7 @@ public: // When outSlot is not nullptr, the current buffer slot index is also // returned. Simiarly, when outFence is not nullptr, the current output // fence is returned. - std::shared_ptr<renderengine::ExternalTexture> getCurrentBuffer( - int* outSlot = nullptr, sp<Fence>* outFence = nullptr) const; + sp<GraphicBuffer> getCurrentBuffer(int* outSlot = nullptr, sp<Fence>* outFence = nullptr) const; // getCurrentCrop returns the cropping rectangle of the current buffer. Rect getCurrentCrop() const; @@ -257,7 +258,7 @@ private: // mCurrentTextureBuffer is the buffer containing the current texture. It's // possible that this buffer is not associated with any buffer slot, so we // must track it separately in order to support the getCurrentBuffer method. - std::shared_ptr<renderengine::ExternalTexture> mCurrentTextureBuffer; + std::shared_ptr<Image> mCurrentTextureBuffer; // mCurrentCrop is the crop rectangle that applies to the current texture. // It gets set each time updateTexImage is called. @@ -336,8 +337,7 @@ private: int mCurrentTexture; // Shadow buffer cache for cleaning up renderengine references. - std::shared_ptr<renderengine::ExternalTexture> - mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex); + std::shared_ptr<Image> mImages[BufferQueueDefs::NUM_BUFFER_SLOTS] GUARDED_BY(mImagesMutex); // Separate mutex guarding the shadow buffer cache. // mImagesMutex can be manipulated with binder threads (e.g. onBuffersAllocated) diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index c533969a5c..ed826a0100 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -71,8 +71,14 @@ BufferStateLayer::~BufferStateLayer() { // original layer and the clone should be removed at the same time so there shouldn't be any // issue with the clone layer trying to use the texture. if (mBufferInfo.mBuffer != nullptr && !isClone()) { - callReleaseBufferCallback(mDrawingState.releaseBufferListener, - mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFence); + // Ensure that mBuffer is uncached from RenderEngine here, as + // RenderEngine may have been using the buffer as an external texture + // after the client uncached the buffer. + auto& engine(mFlinger->getRenderEngine()); + const uint64_t bufferId = mBufferInfo.mBuffer->getId(); + engine.unbindExternalTextureBuffer(bufferId); + callReleaseBufferCallback(mDrawingState.releaseBufferListener, mBufferInfo.mBuffer, + mBufferInfo.mFence); } } @@ -357,9 +363,8 @@ bool BufferStateLayer::addFrameEvent(const sp<Fence>& acquireFence, nsecs_t post return true; } -bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& buffer, - const sp<Fence>& acquireFence, nsecs_t postTime, - nsecs_t desiredPresentTime, bool isAutoTimestamp, +bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence, + nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber, std::optional<nsecs_t> dequeueTime, const FrameTimelineInfo& info, const sp<ITransactionCompletedListener>& releaseBufferListener) { @@ -367,14 +372,12 @@ bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTex if (mCurrentState.buffer) { mReleasePreviousBuffer = true; - if (!mDrawingState.buffer || - mCurrentState.buffer->getBuffer() != mDrawingState.buffer->getBuffer()) { + if (mCurrentState.buffer != mDrawingState.buffer) { // If mCurrentState has a buffer, and we are about to update again // before swapping to drawing state, then the first buffer will be // dropped and we should decrement the pending buffer count and // call any release buffer callbacks if set. - callReleaseBufferCallback(mCurrentState.releaseBufferListener, - mCurrentState.buffer->getBuffer(), + callReleaseBufferCallback(mCurrentState.releaseBufferListener, mCurrentState.buffer, mCurrentState.acquireFence); decrementPendingBufferCount(); if (mCurrentState.bufferSurfaceFrameTX != nullptr) { @@ -412,8 +415,8 @@ bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTex setFrameTimelineVsyncForBufferTransaction(info, postTime); - if (buffer && dequeueTime && *dequeueTime != 0) { - const uint64_t bufferId = buffer->getBuffer()->getId(); + if (dequeueTime && *dequeueTime != 0) { + const uint64_t bufferId = buffer->getId(); mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str()); mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, *dequeueTime, FrameTracer::FrameEvent::DEQUEUE); @@ -421,8 +424,8 @@ bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTex FrameTracer::FrameEvent::QUEUE); } - mCurrentState.width = mCurrentState.buffer->getBuffer()->getWidth(); - mCurrentState.height = mCurrentState.buffer->getBuffer()->getHeight(); + mCurrentState.width = mCurrentState.buffer->width; + mCurrentState.height = mCurrentState.buffer->height; return true; } @@ -671,7 +674,7 @@ status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nse } const int32_t layerId = getSequence(); - const uint64_t bufferId = mDrawingState.buffer->getBuffer()->getId(); + const uint64_t bufferId = mDrawingState.buffer->getId(); const uint64_t frameNumber = mDrawingState.frameNumber; const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence); mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence); @@ -705,7 +708,7 @@ status_t BufferStateLayer::updateActiveBuffer() { return BAD_VALUE; } - if (!mBufferInfo.mBuffer || s.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) { + if (s.buffer != mBufferInfo.mBuffer) { decrementPendingBufferCount(); } @@ -824,13 +827,13 @@ uint32_t BufferStateLayer::getEffectiveScalingMode() const { Rect BufferStateLayer::computeCrop(const State& s) { if (s.crop.isEmpty() && s.buffer) { - return s.buffer->getBuffer()->getBounds(); + return s.buffer->getBounds(); } else if (s.buffer) { Rect crop = s.crop; crop.left = std::max(crop.left, 0); crop.top = std::max(crop.top, 0); - uint32_t bufferWidth = s.buffer->getBuffer()->getWidth(); - uint32_t bufferHeight = s.buffer->getBuffer()->getHeight(); + uint32_t bufferWidth = s.buffer->getWidth(); + uint32_t bufferHeight = s.buffer->getHeight(); if (bufferHeight <= std::numeric_limits<int32_t>::max() && bufferWidth <= std::numeric_limits<int32_t>::max()) { crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth)); @@ -838,7 +841,7 @@ Rect BufferStateLayer::computeCrop(const State& s) { } if (!crop.isValid()) { // Crop rect is out of bounds, return whole buffer - return s.buffer->getBuffer()->getBounds(); + return s.buffer->getBounds(); } return crop; } @@ -860,8 +863,8 @@ bool BufferStateLayer::bufferNeedsFiltering() const { return false; } - uint32_t bufferWidth = s.buffer->getBuffer()->width; - uint32_t bufferHeight = s.buffer->getBuffer()->height; + uint32_t bufferWidth = s.buffer->width; + uint32_t bufferHeight = s.buffer->height; // Undo any transformations on the buffer and return the result. if (s.bufferTransform & ui::Transform::ROT_90) { @@ -888,16 +891,14 @@ void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) { ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers); } -void BufferStateLayer::bufferMayChange(const sp<GraphicBuffer>& newBuffer) { - if (mDrawingState.buffer != nullptr && - (!mBufferInfo.mBuffer || - mDrawingState.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) && - newBuffer != mDrawingState.buffer->getBuffer()) { +void BufferStateLayer::bufferMayChange(sp<GraphicBuffer>& newBuffer) { + if (mDrawingState.buffer != nullptr && mDrawingState.buffer != mBufferInfo.mBuffer && + newBuffer != mDrawingState.buffer) { // If we are about to update mDrawingState.buffer but it has not yet latched // then we will drop a buffer and should decrement the pending buffer count and // call any release buffer callbacks if set. - callReleaseBufferCallback(mDrawingState.releaseBufferListener, - mDrawingState.buffer->getBuffer(), mDrawingState.acquireFence); + callReleaseBufferCallback(mDrawingState.releaseBufferListener, mDrawingState.buffer, + mDrawingState.acquireFence); decrementPendingBufferCount(); } } diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index a69d07f634..8ce3e1f55b 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -66,9 +66,9 @@ public: bool setTransform(uint32_t transform) override; bool setTransformToDisplayInverse(bool transformToDisplayInverse) override; bool setCrop(const Rect& crop) override; - bool setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& buffer, - const sp<Fence>& acquireFence, nsecs_t postTime, nsecs_t desiredPresentTime, - bool isAutoTimestamp, const client_cache_t& clientCacheId, uint64_t frameNumber, + bool setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence, nsecs_t postTime, + nsecs_t desiredPresentTime, bool isAutoTimestamp, + const client_cache_t& clientCacheId, uint64_t frameNumber, std::optional<nsecs_t> dequeueTime, const FrameTimelineInfo& info, const sp<ITransactionCompletedListener>& transactionListener) override; bool setAcquireFence(const sp<Fence>& fence) override; @@ -108,7 +108,7 @@ public: // See mPendingBufferTransactions void decrementPendingBufferCount(); - void bufferMayChange(const sp<GraphicBuffer>& newBuffer) override; + void bufferMayChange(sp<GraphicBuffer>& newBuffer) override; std::atomic<int32_t>* getPendingBufferCounter() override { return &mPendingBufferTransactions; } std::string getPendingBufferCounterName() override { return mBlastTransactionName; } diff --git a/services/surfaceflinger/ClientCache.cpp b/services/surfaceflinger/ClientCache.cpp index f310738423..44b33ef43d 100644 --- a/services/surfaceflinger/ClientCache.cpp +++ b/services/surfaceflinger/ClientCache.cpp @@ -102,12 +102,7 @@ bool ClientCache::add(const client_cache_t& cacheId, const sp<GraphicBuffer>& bu return false; } - LOG_ALWAYS_FATAL_IF(mRenderEngine == nullptr, - "Attempted to build the ClientCache before a RenderEngine instance was " - "ready!"); - processBuffers[id].buffer = std::make_shared< - renderengine::ExternalTexture>(buffer, *mRenderEngine, - renderengine::ExternalTexture::Usage::READABLE); + processBuffers[id].buffer = buffer; return true; } @@ -137,7 +132,7 @@ void ClientCache::erase(const client_cache_t& cacheId) { } } -std::shared_ptr<renderengine::ExternalTexture> ClientCache::get(const client_cache_t& cacheId) { +sp<GraphicBuffer> ClientCache::get(const client_cache_t& cacheId) { std::lock_guard lock(mMutex); ClientCacheBuffer* buf = nullptr; @@ -218,8 +213,8 @@ void ClientCache::dump(std::string& result) { auto &buffers = i.second.second; for (auto& [id, clientCacheBuffer] : buffers) { StringAppendF(&result, "\t ID: %d, Width/Height: %d,%d\n", (int)id, - (int)clientCacheBuffer.buffer->getBuffer()->getWidth(), - (int)clientCacheBuffer.buffer->getBuffer()->getHeight()); + (int)clientCacheBuffer.buffer->getWidth(), + (int)clientCacheBuffer.buffer->getHeight()); } } } diff --git a/services/surfaceflinger/ClientCache.h b/services/surfaceflinger/ClientCache.h index a9b8177d70..0d597c8e05 100644 --- a/services/surfaceflinger/ClientCache.h +++ b/services/surfaceflinger/ClientCache.h @@ -19,7 +19,6 @@ #include <android-base/thread_annotations.h> #include <binder/IBinder.h> #include <gui/LayerState.h> -#include <renderengine/RenderEngine.h> #include <ui/GraphicBuffer.h> #include <utils/RefBase.h> #include <utils/Singleton.h> @@ -40,11 +39,7 @@ public: bool add(const client_cache_t& cacheId, const sp<GraphicBuffer>& buffer); void erase(const client_cache_t& cacheId); - std::shared_ptr<renderengine::ExternalTexture> get(const client_cache_t& cacheId); - - // Always called immediately after setup. Will be set to non-null, and then should never be - // called again. - void setRenderEngine(renderengine::RenderEngine* renderEngine) { mRenderEngine = renderEngine; } + sp<GraphicBuffer> get(const client_cache_t& cacheId); void removeProcess(const wp<IBinder>& processToken); @@ -64,7 +59,7 @@ private: std::mutex mMutex; struct ClientCacheBuffer { - std::shared_ptr<renderengine::ExternalTexture> buffer; + sp<GraphicBuffer> buffer; std::set<wp<ErasedRecipient>> recipients; }; std::map<wp<IBinder> /*caching process*/, @@ -78,7 +73,6 @@ private: }; sp<CacheDeathRecipient> mDeathRecipient; - renderengine::RenderEngine* mRenderEngine = nullptr; bool getBuffer(const client_cache_t& cacheId, ClientCacheBuffer** outClientCacheBuffer) REQUIRES(mMutex); diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h index daee83bd2c..f680460242 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurface.h @@ -16,16 +16,15 @@ #pragma once -#include <renderengine/ExternalTexture.h> +#include <cstdint> +#include <vector> + #include <ui/Fence.h> #include <ui/GraphicTypes.h> #include <ui/Size.h> #include <utils/Errors.h> #include <utils/StrongPointer.h> -#include <cstdint> -#include <vector> - namespace android { class GraphicBuffer; @@ -81,8 +80,7 @@ public: virtual void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) = 0; // Allocates a buffer as scratch space for GPU composition - virtual std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer( - base::unique_fd* bufferFence) = 0; + virtual sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) = 0; // Queues the drawn buffer for consumption by HWC. readyFence is the fence // which will fire when the buffer is ready for consumption. diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h index a8d372c562..a1230b3c4d 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/RenderSurfaceCreationArgs.h @@ -45,8 +45,6 @@ struct RenderSurfaceCreationArgs { // The DisplaySurface for this surface sp<DisplaySurface> displaySurface; - - size_t maxTextureCacheSize; }; /** @@ -83,11 +81,6 @@ public: return *this; } - RenderSurfaceCreationArgsBuilder& setMaxTextureCacheSize(size_t maxTextureCacheSize) { - mArgs.maxTextureCacheSize = maxTextureCacheSize; - return *this; - } - private: RenderSurfaceCreationArgs mArgs; }; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h index c61ec5991b..48a54d6c66 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h @@ -18,7 +18,7 @@ #include <compositionengine/ProjectionSpace.h> #include <compositionengine/impl/HwcBufferCache.h> -#include <renderengine/ExternalTexture.h> +#include <renderengine/Mesh.h> #include <ui/FloatRect.h> #include <ui/GraphicTypes.h> #include <ui/Rect.h> @@ -89,7 +89,7 @@ struct OutputLayerCompositionState { // Overrides the buffer, acquire fence, and display frame stored in LayerFECompositionState struct { - std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr; + sp<GraphicBuffer> buffer = nullptr; sp<Fence> acquireFence = nullptr; Rect displayFrame = {}; ui::Dataspace dataspace{ui::Dataspace::UNKNOWN}; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h index a8a538003e..5127a6f314 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/RenderSurface.h @@ -16,16 +16,12 @@ #pragma once +#include <memory> + #include <android-base/unique_fd.h> #include <compositionengine/RenderSurface.h> #include <utils/StrongPointer.h> -#include <memory> -#include <vector> - -#include "renderengine/ExternalTexture.h" -#include "renderengine/RenderEngine.h" - struct ANativeWindow; namespace android { @@ -58,8 +54,7 @@ public: void setProtected(bool useProtected) override; status_t beginFrame(bool mustRecompose) override; void prepareFrame(bool usesClientComposition, bool usesDeviceComposition) override; - std::shared_ptr<renderengine::ExternalTexture> dequeueBuffer( - base::unique_fd* bufferFence) override; + sp<GraphicBuffer> dequeueBuffer(base::unique_fd* bufferFence) override; void queueBuffer(base::unique_fd readyFence) override; void onPresentDisplayCompleted() override; void flip() override; @@ -71,7 +66,7 @@ public: // Testing void setPageFlipCountForTest(std::uint32_t); void setSizeForTest(const ui::Size&); - std::shared_ptr<renderengine::ExternalTexture>& mutableTextureForTest(); + sp<GraphicBuffer>& mutableGraphicBufferForTest(); base::unique_fd& mutableBufferReadyForTest(); private: @@ -80,13 +75,10 @@ private: // ANativeWindow being rendered into const sp<ANativeWindow> mNativeWindow; - - std::vector<std::shared_ptr<renderengine::ExternalTexture>> mTextureCache; - // Current texture being rendered into - std::shared_ptr<renderengine::ExternalTexture> mTexture; + // Current buffer being rendered into + sp<GraphicBuffer> mGraphicBuffer; const sp<DisplaySurface> mDisplaySurface; ui::Size mSize; - const size_t mMaxTextureCacheSize; bool mProtected{false}; std::uint32_t mPageFlipCount{0}; }; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h index 53f4a30fb8..c5d03a7218 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/CachedSet.h @@ -66,7 +66,7 @@ public: const Rect& getBounds() const { return mBounds; } const Region& getVisibleRegion() const { return mVisibleRegion; } size_t getAge() const { return mAge; } - const std::shared_ptr<renderengine::ExternalTexture>& getBuffer() const { return mTexture; } + const sp<GraphicBuffer>& getBuffer() const { return mTexture.getBuffer(); } const sp<Fence>& getDrawFence() const { return mDrawFence; } const ProjectionSpace& getOutputSpace() const { return mOutputSpace; } ui::Dataspace getOutputDataspace() const { return mOutputDataspace; } @@ -87,7 +87,7 @@ public: void setLastUpdate(std::chrono::steady_clock::time_point now) { mLastUpdate = now; } void append(const CachedSet& other) { - mTexture = nullptr; + mTexture.setBuffer(nullptr, nullptr); mOutputDataspace = ui::Dataspace::UNKNOWN; mDrawFence = nullptr; @@ -115,7 +115,31 @@ private: Region mVisibleRegion; size_t mAge = 0; - std::shared_ptr<renderengine::ExternalTexture> mTexture; + class Texture { + public: + ~Texture() { setBuffer(nullptr, nullptr); } + + void setBuffer(const sp<GraphicBuffer>& buffer, renderengine::RenderEngine* re) { + if (mRE && mBuffer) { + mRE->unbindExternalTextureBuffer(mBuffer->getId()); + } + + mBuffer = buffer; + mRE = re; + + if (mRE && mBuffer) { + mRE->cacheExternalTextureBuffer(mBuffer); + } + } + + const sp<GraphicBuffer>& getBuffer() const { return mBuffer; } + + private: + sp<GraphicBuffer> mBuffer = nullptr; + renderengine::RenderEngine* mRE = nullptr; + }; + + Texture mTexture; sp<Fence> mDrawFence; ProjectionSpace mOutputSpace; ui::Dataspace mOutputDataspace; diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h index fe858c2817..a0cae6fcbb 100644 --- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h +++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/RenderSurface.h @@ -39,7 +39,7 @@ public: MOCK_METHOD1(setBufferPixelFormat, void(ui::PixelFormat)); MOCK_METHOD1(beginFrame, status_t(bool mustRecompose)); MOCK_METHOD2(prepareFrame, void(bool, bool)); - MOCK_METHOD1(dequeueBuffer, std::shared_ptr<renderengine::ExternalTexture>(base::unique_fd*)); + MOCK_METHOD1(dequeueBuffer, sp<GraphicBuffer>(base::unique_fd*)); MOCK_METHOD1(queueBuffer, void(base::unique_fd)); MOCK_METHOD0(onPresentDisplayCompleted, void()); MOCK_METHOD0(flip, void()); diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp index 3468b204fc..3ac5433457 100644 --- a/services/surfaceflinger/CompositionEngine/src/Output.cpp +++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp @@ -14,7 +14,8 @@ * limitations under the License. */ -#include <SurfaceFlingerProperties.sysprop.h> +#include <thread> + #include <android-base/stringprintf.h> #include <compositionengine/CompositionEngine.h> #include <compositionengine/CompositionRefreshArgs.h> @@ -28,9 +29,7 @@ #include <compositionengine/impl/OutputLayerCompositionState.h> #include <compositionengine/impl/planner/Planner.h> -#include <thread> - -#include "renderengine/ExternalTexture.h" +#include <SurfaceFlingerProperties.sysprop.h> // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic push @@ -716,11 +715,11 @@ void Output::writeCompositionState(const compositionengine::CompositionRefreshAr bool skipLayer = false; if (layer->getState().overrideInfo.buffer != nullptr) { if (previousOverride != nullptr && - layer->getState().overrideInfo.buffer->getBuffer() == previousOverride) { + layer->getState().overrideInfo.buffer == previousOverride) { ALOGV("Skipping redundant buffer"); skipLayer = true; } - previousOverride = layer->getState().overrideInfo.buffer->getBuffer(); + previousOverride = layer->getState().overrideInfo.buffer; } const bool includeGeometry = refreshArgs.updatingGeometryThisFrame; @@ -979,15 +978,14 @@ std::optional<base::unique_fd> Output::composeSurfaces( } base::unique_fd fd; - - std::shared_ptr<renderengine::ExternalTexture> tex; + sp<GraphicBuffer> buf; // If we aren't doing client composition on this output, but do have a // flipClientTarget request for this frame on this output, we still need to // dequeue a buffer. if (hasClientComposition || outputState.flipClientTarget) { - tex = mRenderSurface->dequeueBuffer(&fd); - if (tex == nullptr) { + buf = mRenderSurface->dequeueBuffer(&fd); + if (buf == nullptr) { ALOGW("Dequeuing buffer for display [%s] failed, bailing out of " "client composition for this frame", mName.c_str()); @@ -1032,14 +1030,13 @@ std::optional<base::unique_fd> Output::composeSurfaces( // Check if the client composition requests were rendered into the provided graphic buffer. If // so, we can reuse the buffer and avoid client composition. if (mClientCompositionRequestCache) { - if (mClientCompositionRequestCache->exists(tex->getBuffer()->getId(), - clientCompositionDisplay, + if (mClientCompositionRequestCache->exists(buf->getId(), clientCompositionDisplay, clientCompositionLayers)) { outputCompositionState.reusedClientComposition = true; setExpensiveRenderingExpected(false); return readyFence; } - mClientCompositionRequestCache->add(tex->getBuffer()->getId(), clientCompositionDisplay, + mClientCompositionRequestCache->add(buf->getId(), clientCompositionDisplay, clientCompositionLayers); } @@ -1072,12 +1069,12 @@ std::optional<base::unique_fd> Output::composeSurfaces( // over to RenderEngine, in which case this flag can be removed from the drawLayers interface. const bool useFramebufferCache = outputState.layerStackInternal; status_t status = - renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, tex, + renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buf, useFramebufferCache, std::move(fd), &readyFence); if (status != NO_ERROR && mClientCompositionRequestCache) { // If rendering was not successful, remove the request from the cache. - mClientCompositionRequestCache->remove(tex->getBuffer()->getId()); + mClientCompositionRequestCache->remove(buf->getId()); } auto& timeStats = getCompositionEngine().getTimeStats(); @@ -1154,9 +1151,9 @@ std::vector<LayerFE::LayerSettings> Output::generateClientCompositionRequests( std::vector<LayerFE::LayerSettings> results; if (layer->getState().overrideInfo.buffer != nullptr) { - if (layer->getState().overrideInfo.buffer->getBuffer() != previousOverrideBuffer) { + if (layer->getState().overrideInfo.buffer != previousOverrideBuffer) { results = layer->getOverrideCompositionList(); - previousOverrideBuffer = layer->getState().overrideInfo.buffer->getBuffer(); + previousOverrideBuffer = layer->getState().overrideInfo.buffer; ALOGV("Replacing [%s] with override in RE", layer->getLayerFE().getDebugName()); } else { ALOGV("Skipping redundant override buffer for [%s] in RE", diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp index 9ca8914deb..f640f85bca 100644 --- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp +++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp @@ -537,7 +537,7 @@ void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer, sp<GraphicBuffer> buffer = outputIndependentState.buffer; sp<Fence> acquireFence = outputIndependentState.acquireFence; if (getState().overrideInfo.buffer != nullptr) { - buffer = getState().overrideInfo.buffer->getBuffer(); + buffer = getState().overrideInfo.buffer; acquireFence = getState().overrideInfo.acquireFence; } @@ -699,7 +699,7 @@ std::vector<LayerFE::LayerSettings> OutputLayer::getOverrideCompositionList() co settings.geometry = renderengine::Geometry{ .boundaries = boundaries.toFloatRect(), }; - settings.bufferId = getState().overrideInfo.buffer->getBuffer()->getId(); + settings.bufferId = getState().overrideInfo.buffer->getId(); settings.source = renderengine::PixelSource{ .buffer = renderengine::Buffer{ .buffer = getState().overrideInfo.buffer, diff --git a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp index ef50870615..3bef77dde1 100644 --- a/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp +++ b/services/surfaceflinger/CompositionEngine/src/RenderSurface.cpp @@ -25,8 +25,8 @@ #include <compositionengine/impl/DumpHelpers.h> #include <compositionengine/impl/OutputCompositionState.h> #include <compositionengine/impl/RenderSurface.h> + #include <log/log.h> -#include <renderengine/ExternalTexture.h> #include <renderengine/RenderEngine.h> #include <system/window.h> #include <ui/GraphicBuffer.h> @@ -63,8 +63,7 @@ RenderSurface::RenderSurface(const CompositionEngine& compositionEngine, Display mDisplay(display), mNativeWindow(args.nativeWindow), mDisplaySurface(args.displaySurface), - mSize(args.displayWidth, args.displayHeight), - mMaxTextureCacheSize(args.maxTextureCacheSize) { + mSize(args.displayWidth, args.displayHeight) { LOG_ALWAYS_FATAL_IF(!mNativeWindow); } @@ -147,8 +146,7 @@ void RenderSurface::prepareFrame(bool usesClientComposition, bool usesDeviceComp } } -std::shared_ptr<renderengine::ExternalTexture> RenderSurface::dequeueBuffer( - base::unique_fd* bufferFence) { +sp<GraphicBuffer> RenderSurface::dequeueBuffer(base::unique_fd* bufferFence) { ATRACE_CALL(); int fd = -1; ANativeWindowBuffer* buffer = nullptr; @@ -160,41 +158,16 @@ std::shared_ptr<renderengine::ExternalTexture> RenderSurface::dequeueBuffer( mDisplay.getName().c_str(), result); // Return fast here as we can't do much more - any rendering we do // now will just be wrong. - return mTexture; - } - - ALOGW_IF(mTexture != nullptr, "Clobbering a non-null pointer to a buffer [%p].", - mTexture->getBuffer()->getNativeBuffer()->handle); - - sp<GraphicBuffer> newBuffer = GraphicBuffer::from(buffer); - - std::shared_ptr<renderengine::ExternalTexture> texture; - - for (auto it = mTextureCache.begin(); it != mTextureCache.end(); it++) { - const auto& cachedTexture = *it; - if (cachedTexture->getBuffer()->getId() == newBuffer->getId()) { - texture = cachedTexture; - mTextureCache.erase(it); - break; - } + return mGraphicBuffer; } - if (texture) { - mTexture = texture; - } else { - mTexture = std::make_shared< - renderengine::ExternalTexture>(GraphicBuffer::from(buffer), - mCompositionEngine.getRenderEngine(), - renderengine::ExternalTexture::Usage::WRITEABLE); - } - mTextureCache.push_back(mTexture); - if (mTextureCache.size() > mMaxTextureCacheSize) { - mTextureCache.erase(mTextureCache.begin()); - } + ALOGW_IF(mGraphicBuffer != nullptr, "Clobbering a non-null pointer to a buffer [%p].", + mGraphicBuffer->getNativeBuffer()->handle); + mGraphicBuffer = GraphicBuffer::from(buffer); *bufferFence = base::unique_fd(fd); - return mTexture; + return mGraphicBuffer; } void RenderSurface::queueBuffer(base::unique_fd readyFence) { @@ -204,24 +177,24 @@ void RenderSurface::queueBuffer(base::unique_fd readyFence) { // hasFlipClientTargetRequest could return true even if we haven't // dequeued a buffer before. Try dequeueing one if we don't have a // buffer ready. - if (mTexture == nullptr) { + if (mGraphicBuffer == nullptr) { ALOGI("Attempting to queue a client composited buffer without one " "previously dequeued for display [%s]. Attempting to dequeue " "a scratch buffer now", mDisplay.getName().c_str()); - // We shouldn't deadlock here, since mTexture == nullptr only + // We shouldn't deadlock here, since mGraphicBuffer == nullptr only // after a successful call to queueBuffer, or if dequeueBuffer has // never been called. base::unique_fd unused; dequeueBuffer(&unused); } - if (mTexture == nullptr) { + if (mGraphicBuffer == nullptr) { ALOGE("No buffer is ready for display [%s]", mDisplay.getName().c_str()); } else { - status_t result = mNativeWindow->queueBuffer(mNativeWindow.get(), - mTexture->getBuffer()->getNativeBuffer(), - dup(readyFence)); + status_t result = + mNativeWindow->queueBuffer(mNativeWindow.get(), + mGraphicBuffer->getNativeBuffer(), dup(readyFence)); if (result != NO_ERROR) { ALOGE("Error when queueing buffer for display [%s]: %d", mDisplay.getName().c_str(), result); @@ -231,12 +204,11 @@ void RenderSurface::queueBuffer(base::unique_fd readyFence) { LOG_ALWAYS_FATAL("ANativeWindow::queueBuffer failed with error: %d", result); } else { mNativeWindow->cancelBuffer(mNativeWindow.get(), - mTexture->getBuffer()->getNativeBuffer(), - dup(readyFence)); + mGraphicBuffer->getNativeBuffer(), dup(readyFence)); } } - mTexture = nullptr; + mGraphicBuffer = nullptr; } } @@ -284,8 +256,8 @@ void RenderSurface::setSizeForTest(const ui::Size& size) { mSize = size; } -std::shared_ptr<renderengine::ExternalTexture>& RenderSurface::mutableTextureForTest() { - return mTexture; +sp<GraphicBuffer>& RenderSurface::mutableGraphicBufferForTest() { + return mGraphicBuffer; } } // namespace impl diff --git a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp index 53557bbb9f..dcb75556e3 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/CachedSet.cpp @@ -130,7 +130,7 @@ bool CachedSet::hasBufferUpdate() const { } bool CachedSet::hasReadyBuffer() const { - return mTexture != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled; + return mTexture.getBuffer() != nullptr && mDrawFence->getStatus() == Fence::Status::Signaled; } std::vector<CachedSet> CachedSet::decompose() const { @@ -217,27 +217,21 @@ void CachedSet::render(renderengine::RenderEngine& renderEngine, sp<GraphicBuffer> buffer = new GraphicBuffer(static_cast<uint32_t>(mBounds.getWidth()), static_cast<uint32_t>(mBounds.getHeight()), HAL_PIXEL_FORMAT_RGBA_8888, 1, usageFlags); - const auto texture = std::make_shared< - renderengine::ExternalTexture>(buffer, renderEngine, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage::WRITEABLE); LOG_ALWAYS_FATAL_IF(buffer->initCheck() != OK); base::unique_fd drawFence; - status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, mTexture, - false, base::unique_fd(), &drawFence); + status_t result = renderEngine.drawLayers(displaySettings, layerSettingsPointers, buffer, false, + base::unique_fd(), &drawFence); if (result == NO_ERROR) { + mTexture.setBuffer(buffer, &renderEngine); mDrawFence = new Fence(drawFence.release()); mOutputSpace = ProjectionSpace(ui::Size(outputState.framebufferSpace.bounds.getWidth(), outputState.framebufferSpace.bounds.getHeight()), mBounds); - mTexture = std::move(texture); mOutputSpace.orientation = outputState.framebufferSpace.orientation; mOutputDataspace = outputDataspace; mOrientation = orientation; - } else { - mTexture = nullptr; } } diff --git a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp index 3a2534b847..ad7555730d 100644 --- a/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp +++ b/services/surfaceflinger/CompositionEngine/src/planner/Planner.cpp @@ -111,12 +111,7 @@ void Planner::reportFinalPlan( const GraphicBuffer* currentOverrideBuffer = nullptr; bool hasSkippedLayers = false; for (auto layer : layers) { - if (!layer->getState().overrideInfo.buffer) { - continue; - } - - const GraphicBuffer* overrideBuffer = - layer->getState().overrideInfo.buffer->getBuffer().get(); + const GraphicBuffer* overrideBuffer = layer->getState().overrideInfo.buffer.get(); if (overrideBuffer != nullptr && overrideBuffer == currentOverrideBuffer) { // Skip this layer since it is part of a previous cached set hasSkippedLayers = true; diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp index 4c3f4940cc..8a4d161289 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp @@ -26,7 +26,6 @@ #include "MockHWC2.h" #include "MockHWComposer.h" #include "RegionMatcher.h" -#include "renderengine/mock/RenderEngine.h" namespace android::compositionengine { namespace { @@ -716,7 +715,7 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest { static const HdrMetadata kHdrMetadata; static native_handle_t* kSidebandStreamHandle; static const sp<GraphicBuffer> kBuffer; - std::shared_ptr<renderengine::ExternalTexture> kOverrideBuffer; + static const sp<GraphicBuffer> kOverrideBuffer; static const sp<Fence> kFence; static const sp<Fence> kOverrideFence; static const std::string kLayerGenericMetadata1Key; @@ -725,11 +724,6 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest { static const std::vector<uint8_t> kLayerGenericMetadata2Value; OutputLayerWriteStateToHWCTest() { - kOverrideBuffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage:: - WRITEABLE); auto& outputLayerState = mOutputLayer.editState(); outputLayerState.hwc = impl::OutputLayerCompositionState::Hwc(mHwcLayer); @@ -845,7 +839,6 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest { std::shared_ptr<HWC2::mock::Layer> mHwcLayer{std::make_shared<StrictMock<HWC2::mock::Layer>>()}; StrictMock<mock::DisplayColorProfile> mDisplayColorProfile; - renderengine::mock::RenderEngine mRenderEngine; }; const half4 OutputLayerWriteStateToHWCTest::kColor{81.f / 255.f, 82.f / 255.f, 83.f / 255.f, @@ -865,6 +858,7 @@ const HdrMetadata OutputLayerWriteStateToHWCTest::kHdrMetadata{{/* LightFlattena native_handle_t* OutputLayerWriteStateToHWCTest::kSidebandStreamHandle = reinterpret_cast<native_handle_t*>(1031); const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kBuffer; +const sp<GraphicBuffer> OutputLayerWriteStateToHWCTest::kOverrideBuffer = new GraphicBuffer(); const sp<Fence> OutputLayerWriteStateToHWCTest::kFence; const sp<Fence> OutputLayerWriteStateToHWCTest::kOverrideFence = new Fence(); const std::string OutputLayerWriteStateToHWCTest::kLayerGenericMetadata1Key = @@ -1029,7 +1023,7 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) { kOverrideBufferTransform, kOverrideBlendMode, kOverrideAlpha); expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion, kOverrideSurfaceDamage); - expectSetHdrMetadataAndBufferCalls(kOverrideBuffer->getBuffer(), kOverrideFence); + expectSetHdrMetadataAndBufferCalls(kOverrideBuffer, kOverrideFence); expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE); mOutputLayer.writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false); diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp index e80100cc6e..5f0b0eea15 100644 --- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include <cmath> + #include <android-base/stringprintf.h> #include <compositionengine/LayerFECompositionState.h> #include <compositionengine/impl/Output.h> @@ -29,12 +31,9 @@ #include <ui/Rect.h> #include <ui/Region.h> -#include <cmath> - #include "CallOrderStateMachineHelper.h" #include "MockHWC2.h" #include "RegionMatcher.h" -#include "renderengine/ExternalTexture.h" namespace android::compositionengine { namespace { @@ -2961,10 +2960,7 @@ struct OutputComposeSurfacesTest : public testing::Test { mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>(); mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>(); StrictMock<OutputPartialMock> mOutput; - std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage::WRITEABLE); + sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer(); std::optional<base::unique_fd> mReadyFence; }; @@ -3177,10 +3173,7 @@ TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) { EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)) .WillRepeatedly(Return()); - const auto otherOutputBuffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage::WRITEABLE); + sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer(); EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)) .WillOnce(Return(mOutputBuffer)) .WillOnce(Return(otherOutputBuffer)); diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp index 9aeb290eb5..5ef5d7b5cb 100644 --- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp @@ -15,8 +15,6 @@ */ // TODO(b/129481165): remove the #pragma below and fix conversion issues -#include "renderengine/ExternalTexture.h" -#include "ui/GraphicBuffer.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra" @@ -241,9 +239,9 @@ TEST_F(RenderSurfaceTest, dequeueBufferObtainsABuffer) { DoAll(SetArgPointee<0>(buffer.get()), SetArgPointee<1>(-1), Return(NO_ERROR))); base::unique_fd fence; - EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence)->getBuffer().get()); + EXPECT_EQ(buffer.get(), mSurface.dequeueBuffer(&fence).get()); - EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest()->getBuffer().get()); + EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get()); } /* @@ -251,11 +249,8 @@ TEST_F(RenderSurfaceTest, dequeueBufferObtainsABuffer) { */ TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) { - const auto buffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine, - renderengine::ExternalTexture::Usage::READABLE | - renderengine::ExternalTexture::Usage::WRITEABLE); - mSurface.mutableTextureForTest() = buffer; + sp<GraphicBuffer> buffer = new GraphicBuffer(); + mSurface.mutableGraphicBufferForTest() = buffer; impl::OutputCompositionState state; state.usesClientComposition = false; @@ -266,45 +261,43 @@ TEST_F(RenderSurfaceTest, queueBufferHandlesNoClientComposition) { mSurface.queueBuffer(base::unique_fd()); - EXPECT_EQ(buffer.get(), mSurface.mutableTextureForTest().get()); + EXPECT_EQ(buffer.get(), mSurface.mutableGraphicBufferForTest().get()); } TEST_F(RenderSurfaceTest, queueBufferHandlesClientComposition) { - const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(), - mRenderEngine, false); - mSurface.mutableTextureForTest() = buffer; + sp<GraphicBuffer> buffer = new GraphicBuffer(); + mSurface.mutableGraphicBufferForTest() = buffer; impl::OutputCompositionState state; state.usesClientComposition = true; state.flipClientTarget = false; EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state)); - EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1)) + EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1)) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); mSurface.queueBuffer(base::unique_fd()); - EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); + EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get()); } TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequest) { - const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(), - mRenderEngine, false); - mSurface.mutableTextureForTest() = buffer; + sp<GraphicBuffer> buffer = new GraphicBuffer(); + mSurface.mutableGraphicBufferForTest() = buffer; impl::OutputCompositionState state; state.usesClientComposition = false; state.flipClientTarget = true; EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state)); - EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1)) + EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1)) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); mSurface.queueBuffer(base::unique_fd()); - EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); + EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get()); } TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferYetDequeued) { @@ -324,28 +317,27 @@ TEST_F(RenderSurfaceTest, queueBufferHandlesFlipClientTargetRequestWithNoBufferY mSurface.queueBuffer(base::unique_fd()); - EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); + EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get()); } TEST_F(RenderSurfaceTest, queueBufferHandlesNativeWindowQueueBufferFailureOnVirtualDisplay) { - const auto buffer = std::make_shared<renderengine::ExternalTexture>(new GraphicBuffer(), - mRenderEngine, false); - mSurface.mutableTextureForTest() = buffer; + sp<GraphicBuffer> buffer = new GraphicBuffer(); + mSurface.mutableGraphicBufferForTest() = buffer; impl::OutputCompositionState state; state.usesClientComposition = true; EXPECT_CALL(mDisplay, getState()).WillOnce(ReturnRef(state)); - EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getBuffer()->getNativeBuffer(), -1)) + EXPECT_CALL(*mNativeWindow, queueBuffer(buffer->getNativeBuffer(), -1)) .WillOnce(Return(INVALID_OPERATION)); EXPECT_CALL(mDisplay, isVirtual()).WillOnce(Return(true)); - EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getBuffer()->getNativeBuffer(), -1)) + EXPECT_CALL(*mNativeWindow, cancelBuffer(buffer->getNativeBuffer(), -1)) .WillOnce(Return(NO_ERROR)); EXPECT_CALL(*mDisplaySurface, advanceFrame()).Times(1); mSurface.queueBuffer(base::unique_fd()); - EXPECT_EQ(nullptr, mSurface.mutableTextureForTest().get()); + EXPECT_EQ(nullptr, mSurface.mutableGraphicBufferForTest().get()); } /* diff --git a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp index 283c69270f..f01fe27b38 100644 --- a/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp +++ b/services/surfaceflinger/CompositionEngine/tests/planner/CachedSetTest.cpp @@ -305,8 +305,8 @@ TEST_F(CachedSetTest, render) { const auto drawLayers = [&](const renderengine::DisplaySettings& displaySettings, const std::vector<const renderengine::LayerSettings*>& layers, - const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd&&, base::unique_fd*) -> size_t { + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, + base::unique_fd*) -> size_t { EXPECT_EQ(Rect(0, 0, 2, 2), displaySettings.physicalDisplay); EXPECT_EQ(mOutputState.layerStackSpace.content, displaySettings.clip); EXPECT_EQ(ui::Transform::toRotationFlags(mOutputState.framebufferSpace.orientation), @@ -321,6 +321,7 @@ TEST_F(CachedSetTest, render) { EXPECT_CALL(*layerFE1, prepareClientCompositionList(_)).WillOnce(Return(clientCompList1)); EXPECT_CALL(*layerFE2, prepareClientCompositionList(_)).WillOnce(Return(clientCompList2)); EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, _, _, _)).WillOnce(Invoke(drawLayers)); + EXPECT_CALL(mRenderEngine, cacheExternalTextureBuffer(_)); cachedSet.render(mRenderEngine, mOutputState); expectReadyBuffer(cachedSet); @@ -330,6 +331,7 @@ TEST_F(CachedSetTest, render) { cachedSet.getOutputSpace().bounds); // Now check that appending a new cached set properly cleans up RenderEngine resources. + EXPECT_CALL(mRenderEngine, unbindExternalTextureBuffer(_)); CachedSet::Layer& layer3 = *mTestLayers[2]->cachedSetLayer.get(); cachedSet.append(CachedSet(layer3)); } diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp index 8692ee60dc..b7b2cc691b 100644 --- a/services/surfaceflinger/DisplayDevice.cpp +++ b/services/surfaceflinger/DisplayDevice.cpp @@ -70,13 +70,11 @@ DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs& args) mIsPrimary(args.isPrimary) { mCompositionDisplay->editState().isSecure = args.isSecure; mCompositionDisplay->createRenderSurface( - compositionengine:: - RenderSurfaceCreationArgs{ANativeWindow_getWidth(args.nativeWindow.get()), - ANativeWindow_getHeight(args.nativeWindow.get()), - args.nativeWindow, args.displaySurface, - static_cast<size_t>( - SurfaceFlinger:: - maxFrameBufferAcquiredBuffers)}); + compositionengine::RenderSurfaceCreationArgs{ANativeWindow_getWidth( + args.nativeWindow.get()), + ANativeWindow_getHeight( + args.nativeWindow.get()), + args.nativeWindow, args.displaySurface}); if (!mFlinger->mDisableClientCompositionCache && SurfaceFlinger::maxFrameBufferAcquiredBuffers > 0) { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index b12e3fb626..829b91676b 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1050,7 +1050,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { } // Allow BufferStateLayer to release any unlatched buffers in drawing state. - bufferMayChange(c.buffer->getBuffer()); + bufferMayChange(c.buffer); // Commit the transaction commitTransaction(c); @@ -1062,11 +1062,7 @@ uint32_t Layer::doTransaction(uint32_t flags) { void Layer::commitTransaction(State& stateToCommit) { if (auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX; - ((mDrawingState.buffer && stateToCommit.buffer && - mDrawingState.buffer->getBuffer() != stateToCommit.buffer->getBuffer()) || - (mDrawingState.buffer && !stateToCommit.buffer) || - (!mDrawingState.buffer && stateToCommit.buffer)) && - bufferSurfaceFrame != nullptr && + mDrawingState.buffer != stateToCommit.buffer && bufferSurfaceFrame != nullptr && bufferSurfaceFrame->getPresentState() != PresentState::Presented) { // If the previous buffer was committed but not latched (refreshPending - happens during // back to back invalidates), it gets silently dropped here. Mark the corresponding diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 8e51e4139b..64986afd61 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -208,7 +208,7 @@ public: Region transparentRegionHint; - std::shared_ptr<renderengine::ExternalTexture> buffer; + sp<GraphicBuffer> buffer; client_cache_t clientCacheId; sp<Fence> acquireFence; std::shared_ptr<FenceTime> acquireFenceTime; @@ -412,11 +412,10 @@ public: // Used only to set BufferStateLayer state virtual bool setTransform(uint32_t /*transform*/) { return false; }; virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; }; - virtual bool setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& /*buffer*/, - const sp<Fence>& /*acquireFence*/, nsecs_t /*postTime*/, - nsecs_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/, - const client_cache_t& /*clientCacheId*/, uint64_t /* frameNumber */, - std::optional<nsecs_t> /* dequeueTime */, + virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/, const sp<Fence>& /*acquireFence*/, + nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/, + bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/, + uint64_t /* frameNumber */, std::optional<nsecs_t> /* dequeueTime */, const FrameTimelineInfo& /*info*/, const sp<ITransactionCompletedListener>& /* releaseBufferListener */) { return false; @@ -727,7 +726,7 @@ public: * Called before updating the drawing state buffer. Used by BufferStateLayer to release any * unlatched buffers in the drawing state. */ - virtual void bufferMayChange(const sp<GraphicBuffer>& /* newBuffer */){}; + virtual void bufferMayChange(sp<GraphicBuffer>& /* newBuffer */){}; /* * Remove relative z for the layer if its relative parent is not part of the diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp index a9fd16cb75..7a3e433660 100644 --- a/services/surfaceflinger/RefreshRateOverlay.cpp +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -208,8 +208,7 @@ bool RefreshRateOverlay::createLayer() { return true; } -const std::vector<std::shared_ptr<renderengine::ExternalTexture>>& -RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) { +const std::vector<sp<GraphicBuffer>>& RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) { if (mBufferCache.find(fps) == mBufferCache.end()) { // Ensure the range is > 0, so we don't divide by 0. const auto rangeLength = std::max(1u, mHighFps - mLowFps); @@ -223,17 +222,7 @@ RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) { color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale); color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale); color.a = ALPHA; - auto buffers = SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner); - std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures; - std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures), - [&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> { - return std::make_shared< - renderengine::ExternalTexture>(buffer, - mFlinger.getRenderEngine(), - renderengine::ExternalTexture:: - Usage::READABLE); - }); - mBufferCache.emplace(fps, textures); + mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner)); } return mBufferCache[fps]; diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h index aa8329c46a..c16cfa07a4 100644 --- a/services/surfaceflinger/RefreshRateOverlay.h +++ b/services/surfaceflinger/RefreshRateOverlay.h @@ -16,14 +16,13 @@ #pragma once +#include <unordered_map> + #include <math/vec4.h> -#include <renderengine/RenderEngine.h> #include <ui/Rect.h> #include <ui/Size.h> #include <utils/StrongPointer.h> -#include <unordered_map> - #include "Fps.h" namespace android { @@ -71,8 +70,7 @@ private: }; bool createLayer(); - const std::vector<std::shared_ptr<renderengine::ExternalTexture>>& getOrCreateBuffers( - uint32_t fps); + const std::vector<sp<GraphicBuffer>>& getOrCreateBuffers(uint32_t fps); SurfaceFlinger& mFlinger; const sp<Client> mClient; @@ -80,8 +78,7 @@ private: sp<IBinder> mIBinder; sp<IGraphicBufferProducer> mGbp; - std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>> - mBufferCache; + std::unordered_map<int, std::vector<sp<GraphicBuffer>>> mBufferCache; std::optional<int> mCurrentFps; int mFrame = 0; static constexpr float ALPHA = 0.8f; diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp index 00090d948a..d0032ac7fd 100644 --- a/services/surfaceflinger/RegionSamplingThread.cpp +++ b/services/surfaceflinger/RegionSamplingThread.cpp @@ -438,22 +438,18 @@ void RegionSamplingThread::captureSample() { mFlinger.traverseLayersInLayerStack(layerStack, CaptureArgs::UNSET_UID, filterVisitor); }; - std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr; - if (mCachedBuffer && mCachedBuffer->getBuffer()->getWidth() == sampledBounds.getWidth() && - mCachedBuffer->getBuffer()->getHeight() == sampledBounds.getHeight()) { + sp<GraphicBuffer> buffer = nullptr; + if (mCachedBuffer && mCachedBuffer->getWidth() == sampledBounds.getWidth() && + mCachedBuffer->getHeight() == sampledBounds.getHeight()) { buffer = mCachedBuffer; } else { const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; - sp<GraphicBuffer> graphicBuffer = - new GraphicBuffer(sampledBounds.getWidth(), sampledBounds.getHeight(), - PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread"); - const status_t bufferStatus = graphicBuffer->initCheck(); + buffer = new GraphicBuffer(sampledBounds.getWidth(), sampledBounds.getHeight(), + PIXEL_FORMAT_RGBA_8888, 1, usage, "RegionSamplingThread"); + const status_t bufferStatus = buffer->initCheck(); LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureSample: Buffer failed to allocate: %d", bufferStatus); - buffer = std::make_shared< - renderengine::ExternalTexture>(graphicBuffer, mFlinger.getRenderEngine(), - renderengine::ExternalTexture::Usage::WRITEABLE); } const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener(); @@ -469,8 +465,8 @@ void RegionSamplingThread::captureSample() { } ALOGV("Sampling %zu descriptors", activeDescriptors.size()); - std::vector<float> lumas = sampleBuffer(buffer->getBuffer(), sampledBounds.leftTop(), - activeDescriptors, orientation); + std::vector<float> lumas = + sampleBuffer(buffer, sampledBounds.leftTop(), activeDescriptors, orientation); if (lumas.size() != activeDescriptors.size()) { ALOGW("collected %zu median luma values for %zu descriptors", lumas.size(), activeDescriptors.size()); @@ -481,6 +477,16 @@ void RegionSamplingThread::captureSample() { activeDescriptors[d].listener->onSampleCollected(lumas[d]); } + // Extend the lifetime of mCachedBuffer from the previous frame to here to ensure that: + // 1) The region sampling thread is the last owner of the buffer, and the freeing of the buffer + // happens in this thread, as opposed to the main thread. + // 2) The listener(s) receive their notifications prior to freeing the buffer. + if (mCachedBuffer != nullptr && mCachedBuffer != buffer) { + if (mFlinger.getRenderEngine().getRenderEngineType() == + renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) { + mFlinger.getRenderEngine().unbindExternalTextureBuffer(mCachedBuffer->getId()); + } + } mCachedBuffer = buffer; ATRACE_INT(lumaSamplingStepTag, static_cast<int>(samplingStep::noWorkNeeded)); } diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h index 86632db490..0defdb3fcb 100644 --- a/services/surfaceflinger/RegionSamplingThread.h +++ b/services/surfaceflinger/RegionSamplingThread.h @@ -16,19 +16,17 @@ #pragma once -#include <android-base/thread_annotations.h> -#include <binder/IBinder.h> -#include <renderengine/ExternalTexture.h> -#include <ui/GraphicBuffer.h> -#include <ui/Rect.h> -#include <utils/StrongPointer.h> - #include <chrono> #include <condition_variable> #include <mutex> #include <thread> #include <unordered_map> +#include <android-base/thread_annotations.h> +#include <binder/IBinder.h> +#include <ui/GraphicBuffer.h> +#include <ui/Rect.h> +#include <utils/StrongPointer.h> #include "Scheduler/OneShotTimer.h" namespace android { @@ -124,8 +122,7 @@ private: std::mutex mSamplingMutex; std::unordered_map<wp<IBinder>, Descriptor, WpHash> mDescriptors GUARDED_BY(mSamplingMutex); - std::shared_ptr<renderengine::ExternalTexture> mCachedBuffer GUARDED_BY(mSamplingMutex) = - nullptr; + sp<GraphicBuffer> mCachedBuffer GUARDED_BY(mSamplingMutex) = nullptr; }; } // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index e66f65b71e..02579c6bde 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -735,7 +735,6 @@ void SurfaceFlinger::init() { mCompositionEngine->setTimeStats(mTimeStats); mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName)); mCompositionEngine->getHwComposer().setConfiguration(this, getBE().mComposerSequenceId); - ClientCache::getInstance().setRenderEngine(&getRenderEngine()); // Process any initial hotplug and resulting display changes. processDisplayHotplugEventsLocked(); const auto display = getDefaultDisplayDeviceLocked(); @@ -3708,6 +3707,7 @@ void SurfaceFlinger::applyTransactionState(const FrameTimelineInfo& frameTimelin if (uncacheBuffer.isValid()) { ClientCache::getInstance().erase(uncacheBuffer); + getRenderEngine().unbindExternalTextureBuffer(uncacheBuffer.id); } // If a synchronous transaction is explicitly requested without any changes, force a transaction @@ -4083,16 +4083,23 @@ uint32_t SurfaceFlinger::setClientStateLocked( } bool bufferChanged = what & layer_state_t::eBufferChanged; bool cacheIdChanged = what & layer_state_t::eCachedBufferChanged; - std::shared_ptr<renderengine::ExternalTexture> buffer; + sp<GraphicBuffer> buffer; if (bufferChanged && cacheIdChanged && s.buffer != nullptr) { - ClientCache::getInstance().add(s.cachedBuffer, s.buffer); - buffer = ClientCache::getInstance().get(s.cachedBuffer); + buffer = s.buffer; + bool success = ClientCache::getInstance().add(s.cachedBuffer, s.buffer); + if (success) { + getRenderEngine().cacheExternalTextureBuffer(s.buffer); + success = ClientCache::getInstance() + .registerErasedRecipient(s.cachedBuffer, + wp<ClientCache::ErasedRecipient>(this)); + if (!success) { + getRenderEngine().unbindExternalTextureBuffer(s.buffer->getId()); + } + } } else if (cacheIdChanged) { buffer = ClientCache::getInstance().get(s.cachedBuffer); } else if (bufferChanged) { - buffer = std::make_shared< - renderengine::ExternalTexture>(s.buffer, getRenderEngine(), - renderengine::ExternalTexture::Usage::READABLE); + buffer = s.buffer; } if (buffer) { const bool frameNumberChanged = what & layer_state_t::eFrameNumberChanged; @@ -5996,17 +6003,15 @@ status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, const status_t bufferStatus = buffer->initCheck(); LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "captureScreenCommon: Buffer failed to allocate: %d", bufferStatus); - const auto texture = std::make_shared< - renderengine::ExternalTexture>(buffer, getRenderEngine(), - renderengine::ExternalTexture::Usage::WRITEABLE); - return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, texture, + return captureScreenCommon(std::move(renderAreaFuture), traverseLayers, buffer, false /* regionSampling */, grayscale, captureListener); } -status_t SurfaceFlinger::captureScreenCommon( - RenderAreaFuture renderAreaFuture, TraverseLayersFunction traverseLayers, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling, - bool grayscale, const sp<IScreenCaptureListener>& captureListener) { +status_t SurfaceFlinger::captureScreenCommon(RenderAreaFuture renderAreaFuture, + TraverseLayersFunction traverseLayers, + sp<GraphicBuffer>& buffer, bool regionSampling, + bool grayscale, + const sp<IScreenCaptureListener>& captureListener) { ATRACE_CALL(); if (captureListener == nullptr) { @@ -6039,6 +6044,15 @@ status_t SurfaceFlinger::captureScreenCommon( regionSampling, grayscale, captureResults); }); + // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine + // Only do this when we're not doing region sampling, to allow the region sampling thread to + // manage buffer lifecycle itself. + if (!regionSampling && + getRenderEngine().getRenderEngineType() == + renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED) { + getRenderEngine().unbindExternalTextureBuffer(buffer->getId()); + } + captureResults.result = result; captureListener->onScreenCaptureCompleted(captureResults); })); @@ -6046,10 +6060,11 @@ status_t SurfaceFlinger::captureScreenCommon( return NO_ERROR; } -status_t SurfaceFlinger::renderScreenImplLocked( - const RenderArea& renderArea, TraverseLayersFunction traverseLayers, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool forSystem, - bool regionSampling, bool grayscale, ScreenCaptureResults& captureResults) { +status_t SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea, + TraverseLayersFunction traverseLayers, + const sp<GraphicBuffer>& buffer, bool forSystem, + bool regionSampling, bool grayscale, + ScreenCaptureResults& captureResults) { ATRACE_CALL(); traverseLayers([&](Layer* layer) { @@ -6057,7 +6072,7 @@ status_t SurfaceFlinger::renderScreenImplLocked( captureResults.capturedSecureLayers || (layer->isVisible() && layer->isSecure()); }); - const bool useProtected = buffer->getBuffer()->getUsage() & GRALLOC_USAGE_PROTECTED; + const bool useProtected = buffer->getUsage() & GRALLOC_USAGE_PROTECTED; // We allow the system server to take screenshots of secure layers for // use in situations like the Screen-rotation animation and place @@ -6067,7 +6082,7 @@ status_t SurfaceFlinger::renderScreenImplLocked( return PERMISSION_DENIED; } - captureResults.buffer = buffer->getBuffer(); + captureResults.buffer = buffer; captureResults.capturedDataspace = renderArea.getReqDataSpace(); const auto reqWidth = renderArea.getReqWidth(); @@ -6158,9 +6173,11 @@ status_t SurfaceFlinger::renderScreenImplLocked( base::unique_fd drawFence; getRenderEngine().useProtectedContext(useProtected); - const constexpr bool kUseFramebufferCache = false; + // TODO(b/180767535): Remove this once we optimize buffer lifecycle for RenderEngine + const bool useFramebufferCache = getRenderEngine().getRenderEngineType() == + renderengine::RenderEngine::RenderEngineType::SKIA_GL_THREADED; getRenderEngine().drawLayers(clientCompositionDisplay, clientCompositionLayerPointers, buffer, - kUseFramebufferCache, std::move(bufferFence), &drawFence); + useFramebufferCache, std::move(bufferFence), &drawFence); if (drawFence >= 0) { sp<Fence> releaseFence = new Fence(dup(drawFence)); @@ -6425,6 +6442,10 @@ void SurfaceFlinger::removeFromOffscreenLayers(Layer* layer) { mOffscreenLayers.erase(layer); } +void SurfaceFlinger::bufferErased(const client_cache_t& clientCacheId) { + getRenderEngine().unbindExternalTextureBuffer(clientCacheId.id); +} + status_t SurfaceFlinger::setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor, float lightPosY, float lightPosZ, float lightRadius) { diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a242d8a876..b3da61e810 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -184,6 +184,7 @@ public: class SurfaceFlinger : public BnSurfaceComposer, public PriorityDumper, + public ClientCache::ErasedRecipient, private IBinder::DeathRecipient, private HWC2::ComposerCallback, private ISchedulerCallback { @@ -331,6 +332,9 @@ public: wp<Layer> fromHandle(const sp<IBinder>& handle); wp<Layer> fromHandleLocked(const sp<IBinder>& handle) const REQUIRES(mStateLock); + // Inherit from ClientCache::ErasedRecipient + void bufferErased(const client_cache_t& clientCacheId) override; + // If set, disables reusing client composition buffers. This can be set by // debug.sf.disable_client_composition_cache bool mDisableClientCompositionCache = false; @@ -903,14 +907,12 @@ private: status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, ui::Size bufferSize, ui::PixelFormat, bool allowProtected, bool grayscale, const sp<IScreenCaptureListener>&); - status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, - const std::shared_ptr<renderengine::ExternalTexture>&, + status_t captureScreenCommon(RenderAreaFuture, TraverseLayersFunction, sp<GraphicBuffer>&, bool regionSampling, bool grayscale, const sp<IScreenCaptureListener>&); status_t renderScreenImplLocked(const RenderArea&, TraverseLayersFunction, - const std::shared_ptr<renderengine::ExternalTexture>&, - bool forSystem, bool regionSampling, bool grayscale, - ScreenCaptureResults&); + const sp<GraphicBuffer>&, bool forSystem, bool regionSampling, + bool grayscale, ScreenCaptureResults&); sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack) REQUIRES(mStateLock); sp<DisplayDevice> getDisplayById(DisplayId displayId) const REQUIRES(mStateLock); diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp index 3042450f29..4e1c0c77ea 100644 --- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp +++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp @@ -15,7 +15,6 @@ */ // TODO(b/129481165): remove the #pragma below and fix conversion issues -#include "renderengine/ExternalTexture.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" #pragma clang diagnostic ignored "-Wextra" @@ -195,7 +194,7 @@ public: sp<Fence> mClientTargetAcquireFence = Fence::NO_FENCE; - std::shared_ptr<renderengine::ExternalTexture> mCaptureScreenBuffer; + sp<GraphicBuffer> mCaptureScreenBuffer; }; template <typename LayerCase> @@ -244,15 +243,11 @@ void CompositionTest::captureScreenComposition() { // TODO: Eliminate expensive/real allocation if possible. const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE; - mCaptureScreenBuffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(renderArea->getReqWidth(), - renderArea->getReqHeight(), - HAL_PIXEL_FORMAT_RGBA_8888, 1, usage, - "screenshot"), - *mRenderEngine, true); + mCaptureScreenBuffer = new GraphicBuffer(renderArea->getReqWidth(), renderArea->getReqHeight(), + HAL_PIXEL_FORMAT_RGBA_8888, 1, usage, "screenshot"); status_t result = - mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer, + mFlinger.renderScreenImplLocked(*renderArea, traverseLayers, mCaptureScreenBuffer.get(), forSystem, regionSampling); EXPECT_EQ(NO_ERROR, result); @@ -345,8 +340,8 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillRepeatedly([](const renderengine::DisplaySettings& displaySettings, const std::vector<const renderengine::LayerSettings*>&, - const std::shared_ptr<renderengine::ExternalTexture>&, - const bool, base::unique_fd&&, base::unique_fd*) -> status_t { + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -394,8 +389,8 @@ struct BaseDisplayVariant { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillRepeatedly([](const renderengine::DisplaySettings& displaySettings, const std::vector<const renderengine::LayerSettings*>&, - const std::shared_ptr<renderengine::ExternalTexture>&, - const bool, base::unique_fd&&, base::unique_fd*) -> status_t { + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -630,8 +625,8 @@ struct BaseLayerProperties { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([](const renderengine::DisplaySettings& displaySettings, const std::vector<const renderengine::LayerSettings*>& layerSettings, - const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd&&, base::unique_fd*) -> status_t { + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -679,8 +674,8 @@ struct BaseLayerProperties { EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([](const renderengine::DisplaySettings& displaySettings, const std::vector<const renderengine::LayerSettings*>& layerSettings, - const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd&&, base::unique_fd*) -> status_t { + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); @@ -756,8 +751,8 @@ struct CommonSecureLayerProperties : public BaseLayerProperties<LayerProperties> EXPECT_CALL(*test->mRenderEngine, drawLayers) .WillOnce([](const renderengine::DisplaySettings& displaySettings, const std::vector<const renderengine::LayerSettings*>& layerSettings, - const std::shared_ptr<renderengine::ExternalTexture>&, const bool, - base::unique_fd&&, base::unique_fd*) -> status_t { + const sp<GraphicBuffer>&, const bool, base::unique_fd&&, + base::unique_fd*) -> status_t { EXPECT_EQ(DEFAULT_DISPLAY_MAX_LUMINANCE, displaySettings.maxLuminance); EXPECT_EQ(Rect(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT), displaySettings.physicalDisplay); diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h index d004b9d9eb..63baf7dee2 100644 --- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h @@ -352,8 +352,8 @@ public: auto renderScreenImplLocked(const RenderArea& renderArea, SurfaceFlinger::TraverseLayersFunction traverseLayers, - const std::shared_ptr<renderengine::ExternalTexture>& buffer, - bool forSystem, bool regionSampling) { + const sp<GraphicBuffer>& buffer, bool forSystem, + bool regionSampling) { ScreenCaptureResults captureResults; return mFlinger->renderScreenImplLocked(renderArea, traverseLayers, buffer, forSystem, regionSampling, false /* grayscale */, diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp index 690a7fd757..b5ef0a1334 100644 --- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp @@ -21,8 +21,6 @@ #include <gtest/gtest.h> #include <gui/SurfaceComposerClient.h> #include <log/log.h> -#include <renderengine/ExternalTexture.h> -#include <renderengine/mock/RenderEngine.h> #include <utils/String8.h> #include "TestableSurfaceFlinger.h" @@ -104,7 +102,6 @@ public: TestableSurfaceFlinger mFlinger; Hwc2::mock::Composer* mComposer = nullptr; - renderengine::mock::RenderEngine mRenderEngine; FenceToFenceTimeMap fenceFactory; client_cache_t mClientCache; @@ -112,12 +109,9 @@ public: sp<BufferStateLayer> layer = createBufferStateLayer(); sp<Fence> fence(new Fence()); - const auto buffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; int32_t layerId = layer->getSequence(); - uint64_t bufferId = buffer->getBuffer()->getId(); + uint64_t bufferId = buffer->getId(); uint64_t frameNumber = 5; nsecs_t dequeueTime = 10; nsecs_t postTime = 20; diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp index 6ff6e908fa..c75538f476 100644 --- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp +++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp @@ -21,8 +21,6 @@ #include <gtest/gtest.h> #include <gui/SurfaceComposerClient.h> #include <log/log.h> -#include <renderengine/ExternalTexture.h> -#include <renderengine/mock/RenderEngine.h> #include <utils/String8.h> #include "TestableSurfaceFlinger.h" @@ -106,7 +104,6 @@ public: TestableSurfaceFlinger mFlinger; Hwc2::mock::Composer* mComposer = nullptr; - renderengine::mock::RenderEngine mRenderEngine; FenceToFenceTimeMap fenceFactory; client_cache_t mClientCache; @@ -127,10 +124,7 @@ public: sp<BufferStateLayer> layer = createBufferStateLayer(); sp<Fence> fence(new Fence()); auto acquireFence = fenceFactory.createFenceTimeForTest(fence); - const auto buffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); acquireFence->signalForTest(12); @@ -155,10 +149,7 @@ public: sp<Fence> fence1(new Fence()); auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); - const auto buffer1 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); @@ -167,10 +158,7 @@ public: sp<Fence> fence2(new Fence()); auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2); - const auto buffer2 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; nsecs_t start = systemTime(); layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); @@ -208,10 +196,8 @@ public: sp<Fence> fence(new Fence()); auto acquireFence = fenceFactory.createFenceTimeForTest(fence); - const auto buffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; + layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); acquireFence->signalForTest(12); @@ -236,10 +222,8 @@ public: sp<BufferStateLayer> layer = createBufferStateLayer(); sp<Fence> fence(new Fence()); auto acquireFence = fenceFactory.createFenceTimeForTest(fence); - const auto buffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; + layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); @@ -268,10 +252,8 @@ public: sp<Fence> fence(new Fence()); auto acquireFence = fenceFactory.createFenceTimeForTest(fence); - const auto buffer = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; + layer->setBuffer(buffer, fence, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 3, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(2u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); @@ -369,10 +351,7 @@ public: sp<Fence> fence1(new Fence()); auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); - const auto buffer1 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); ASSERT_NE(nullptr, layer->mCurrentState.bufferSurfaceFrameTX); @@ -380,10 +359,7 @@ public: sp<Fence> fence2(new Fence()); auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2); - const auto buffer2 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); acquireFence2->signalForTest(12); @@ -410,10 +386,7 @@ public: sp<Fence> fence1(new Fence()); auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1); - const auto buffer1 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); EXPECT_EQ(0u, layer->mCurrentState.bufferlessSurfaceFramesTX.size()); @@ -422,10 +395,7 @@ public: sp<Fence> fence2(new Fence()); auto acquireFence2 = fenceFactory.createFenceTimeForTest(fence2); - const auto buffer2 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer2{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; auto dropStartTime1 = systemTime(); layer->setBuffer(buffer2, fence2, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ FrameTimelineInfo::INVALID_VSYNC_ID, /*inputEventId*/ 0}, @@ -437,10 +407,7 @@ public: sp<Fence> fence3(new Fence()); auto acquireFence3 = fenceFactory.createFenceTimeForTest(fence3); - const auto buffer3 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, - 1, 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer3{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; auto dropStartTime2 = systemTime(); layer->setBuffer(buffer3, fence3, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 2, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); @@ -480,11 +447,7 @@ public: std::vector<std::shared_ptr<frametimeline::SurfaceFrame>> bufferlessSurfaceFrames; for (int i = 0; i < 10; i += 2) { sp<Fence> fence1(new Fence()); - const auto buffer1 = std::make_shared< - renderengine::ExternalTexture>(new GraphicBuffer(1, 1, - HAL_PIXEL_FORMAT_RGBA_8888, 1, - 0), - mRenderEngine, false); + sp<GraphicBuffer> buffer1{new GraphicBuffer(1, 1, HAL_PIXEL_FORMAT_RGBA_8888, 1, 0)}; layer->setBuffer(buffer1, fence1, 10, 20, false, mClientCache, 1, std::nullopt, {/*vsyncId*/ 1, /*inputEventId*/ 0}, nullptr /* releaseBufferCallback */); |