Loading libs/renderengine/skia/SkiaRenderEngine.cpp +10 −5 Original line number Diff line number Diff line Loading @@ -510,7 +510,8 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader( auto effect = shaders::LinearEffect{.inputDataspace = parameters.layer.sourceDataspace, .outputDataspace = parameters.outputDataSpace, .undoPremultipliedAlpha = parameters.undoPremultipliedAlpha}; .undoPremultipliedAlpha = parameters.undoPremultipliedAlpha, .fakeOutputDataspace = parameters.fakeOutputDataspace}; auto effectIter = mRuntimeEffects.find(effect); sk_sp<SkRuntimeEffect> runtimeEffect = nullptr; Loading Loading @@ -906,12 +907,14 @@ void SkiaRenderEngine::drawLayersInternal( (display.outputDataspace & ui::Dataspace::TRANSFER_MASK) == static_cast<int32_t>(ui::Dataspace::TRANSFER_SRGB); const ui::Dataspace runtimeEffectDataspace = !dimInLinearSpace && isExtendedHdr const bool useFakeOutputDataspaceForRuntimeEffect = !dimInLinearSpace && isExtendedHdr; const ui::Dataspace fakeDataspace = useFakeOutputDataspaceForRuntimeEffect ? static_cast<ui::Dataspace>( (display.outputDataspace & ui::Dataspace::STANDARD_MASK) | ui::Dataspace::TRANSFER_GAMMA2_2 | (display.outputDataspace & ui::Dataspace::RANGE_MASK)) : display.outputDataspace; : ui::Dataspace::UNKNOWN; // If the input dataspace is range extended, the output dataspace transfer is sRGB // and dimmingStage is GAMMA_OETF, dim in linear space instead, and Loading Loading @@ -1018,7 +1021,8 @@ void SkiaRenderEngine::drawLayersInternal( .layerDimmingRatio = dimInLinearSpace ? layerDimmingRatio : 1.f, .outputDataSpace = runtimeEffectDataspace})); .outputDataSpace = display.outputDataspace, .fakeOutputDataspace = fakeDataspace})); // Turn on dithering when dimming beyond this (arbitrary) threshold... static constexpr float kDimmingThreshold = 0.2f; Loading Loading @@ -1082,7 +1086,8 @@ void SkiaRenderEngine::drawLayersInternal( .undoPremultipliedAlpha = false, .requiresLinearEffect = requiresLinearEffect, .layerDimmingRatio = layerDimmingRatio, .outputDataSpace = runtimeEffectDataspace})); .outputDataSpace = display.outputDataspace, .fakeOutputDataspace = fakeDataspace})); } if (layer.disableBlending) { Loading libs/renderengine/skia/SkiaRenderEngine.h +1 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ private: bool requiresLinearEffect; float layerDimmingRatio; const ui::Dataspace outputDataSpace; const ui::Dataspace fakeOutputDataspace; }; sk_sp<SkShader> createRuntimeEffectShader(const RuntimeEffectShaderParameters&); Loading libs/shaders/shaders.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -168,8 +168,8 @@ void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, void generateOETF(std::string& shader) { // Only support gamma 2.2 for now shader.append(R"( float OETF(float3 linear) { return sign(linear) * pow(abs(linear), (1.0 / 2.2)); float3 OETF(float3 linear) { return sign(linear) * pow(abs(linear), float3(1.0 / 2.2)); } )"); } Loading services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h +10 −7 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public: TexturePool(renderengine::RenderEngine& renderEngine) : mRenderEngine(renderEngine), mEnabled(false) {} virtual ~TexturePool() = default; virtual ~TexturePool(); // Sets the display size for the texture pool. // This will trigger a reallocation for all remaining textures in the pool. Loading @@ -83,11 +83,10 @@ public: // be held by the pool. This is useful when the active display changes. void setEnabled(bool enable); void dump(std::string& out) const; void dump(std::string& out) const EXCLUDES(mMutex); protected: // Proteted visibility so that they can be used for testing const static constexpr size_t kMinPoolSize = 3; const static constexpr size_t kMaxPoolSize = 4; struct Entry { Loading @@ -96,16 +95,20 @@ protected: }; std::deque<Entry> mPool; std::future<std::shared_ptr<renderengine::ExternalTexture>> mGenTextureFuture; private: std::shared_ptr<renderengine::ExternalTexture> genTexture(); std::shared_ptr<renderengine::ExternalTexture> genTexture(ui::Size size); // Returns a previously borrowed texture to the pool. void returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& texture, const sp<Fence>& fence); void allocatePool(); renderengine::RenderEngine& mRenderEngine; ui::Size mSize; void genTextureAsyncIfNeeded() REQUIRES(mMutex); void resetPool() REQUIRES(mMutex); renderengine::RenderEngine& mRenderEngine GUARDED_BY(mRenderEngineMutex); ui::Size mSize GUARDED_BY(mMutex); bool mEnabled; mutable std::mutex mMutex; mutable std::mutex mRenderEngineMutex; }; } // namespace android::compositionengine::impl::planner services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp +50 −14 Original line number Diff line number Diff line Loading @@ -25,31 +25,61 @@ namespace android::compositionengine::impl::planner { void TexturePool::allocatePool() { TexturePool::~TexturePool() { if (mGenTextureFuture.valid()) { mGenTextureFuture.get(); } } void TexturePool::resetPool() { if (mGenTextureFuture.valid()) { mGenTextureFuture.get(); } mPool.clear(); if (mEnabled && mSize.isValid()) { mPool.resize(kMinPoolSize); std::generate_n(mPool.begin(), kMinPoolSize, [&]() { return Entry{genTexture(), nullptr}; }); genTextureAsyncIfNeeded(); } // Generate a new texture asynchronously so it will not require allocation on the main // thread. void TexturePool::genTextureAsyncIfNeeded() { if (mEnabled && mSize.isValid() && !mGenTextureFuture.valid()) { mGenTextureFuture = std::async( std::launch::async, [&](ui::Size size) { return genTexture(size); }, mSize); } } void TexturePool::setDisplaySize(ui::Size size) { std::lock_guard lock(mMutex); if (mSize == size) { return; } mSize = size; allocatePool(); resetPool(); } std::shared_ptr<TexturePool::AutoTexture> TexturePool::borrowTexture() { if (mPool.empty()) { return std::make_shared<AutoTexture>(*this, genTexture(), nullptr); std::lock_guard lock(mMutex); std::shared_ptr<TexturePool::AutoTexture> tex; if (mGenTextureFuture.valid()) { tex = std::make_shared<AutoTexture>(*this, mGenTextureFuture.get(), nullptr); } else { tex = std::make_shared<AutoTexture>(*this, genTexture(mSize), nullptr); } // Speculatively generate a new texture, so that the next call does not need // to wait for allocation. genTextureAsyncIfNeeded(); return tex; } const auto entry = mPool.front(); mPool.pop_front(); if (mPool.empty()) { std::lock_guard lock(mMutex); // Similiarly generate a new texture when lending out the last entry, so that // the next call does not need to wait for allocation. genTextureAsyncIfNeeded(); } return std::make_shared<AutoTexture>(*this, entry.texture, entry.fence); } Loading @@ -60,6 +90,8 @@ void TexturePool::returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& return; } std::lock_guard lock(mMutex); // Or the texture on the floor if the pool is no longer tracking textures of the same size. if (static_cast<int32_t>(texture->getBuffer()->getWidth()) != mSize.getWidth() || static_cast<int32_t>(texture->getBuffer()->getHeight()) != mSize.getHeight()) { Loading @@ -80,13 +112,14 @@ void TexturePool::returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& mPool.push_back({std::move(texture), fence}); } std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture() { LOG_ALWAYS_FATAL_IF(!mSize.isValid(), "Attempted to generate texture with invalid size"); std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture(ui::Size size) { std::lock_guard lock(mRenderEngineMutex); LOG_ALWAYS_FATAL_IF(!size.isValid(), "Attempted to generate texture with invalid size"); return std::make_shared< renderengine::impl:: ExternalTexture>(sp<GraphicBuffer>:: make(static_cast<uint32_t>(mSize.getWidth()), static_cast<uint32_t>(mSize.getHeight()), make(static_cast<uint32_t>(size.getWidth()), static_cast<uint32_t>(size.getHeight()), HAL_PIXEL_FORMAT_RGBA_8888, 1U, static_cast<uint64_t>( GraphicBuffer::USAGE_HW_RENDER | Loading @@ -100,10 +133,13 @@ std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture() { void TexturePool::setEnabled(bool enabled) { mEnabled = enabled; allocatePool(); std::lock_guard lock(mMutex); resetPool(); } void TexturePool::dump(std::string& out) const { std::lock_guard lock(mMutex); base::StringAppendF(&out, "TexturePool (%s) has %zu buffers of size [%" PRId32 ", %" PRId32 "]\n", mEnabled ? "enabled" : "disabled", mPool.size(), mSize.width, mSize.height); Loading Loading
libs/renderengine/skia/SkiaRenderEngine.cpp +10 −5 Original line number Diff line number Diff line Loading @@ -510,7 +510,8 @@ sk_sp<SkShader> SkiaRenderEngine::createRuntimeEffectShader( auto effect = shaders::LinearEffect{.inputDataspace = parameters.layer.sourceDataspace, .outputDataspace = parameters.outputDataSpace, .undoPremultipliedAlpha = parameters.undoPremultipliedAlpha}; .undoPremultipliedAlpha = parameters.undoPremultipliedAlpha, .fakeOutputDataspace = parameters.fakeOutputDataspace}; auto effectIter = mRuntimeEffects.find(effect); sk_sp<SkRuntimeEffect> runtimeEffect = nullptr; Loading Loading @@ -906,12 +907,14 @@ void SkiaRenderEngine::drawLayersInternal( (display.outputDataspace & ui::Dataspace::TRANSFER_MASK) == static_cast<int32_t>(ui::Dataspace::TRANSFER_SRGB); const ui::Dataspace runtimeEffectDataspace = !dimInLinearSpace && isExtendedHdr const bool useFakeOutputDataspaceForRuntimeEffect = !dimInLinearSpace && isExtendedHdr; const ui::Dataspace fakeDataspace = useFakeOutputDataspaceForRuntimeEffect ? static_cast<ui::Dataspace>( (display.outputDataspace & ui::Dataspace::STANDARD_MASK) | ui::Dataspace::TRANSFER_GAMMA2_2 | (display.outputDataspace & ui::Dataspace::RANGE_MASK)) : display.outputDataspace; : ui::Dataspace::UNKNOWN; // If the input dataspace is range extended, the output dataspace transfer is sRGB // and dimmingStage is GAMMA_OETF, dim in linear space instead, and Loading Loading @@ -1018,7 +1021,8 @@ void SkiaRenderEngine::drawLayersInternal( .layerDimmingRatio = dimInLinearSpace ? layerDimmingRatio : 1.f, .outputDataSpace = runtimeEffectDataspace})); .outputDataSpace = display.outputDataspace, .fakeOutputDataspace = fakeDataspace})); // Turn on dithering when dimming beyond this (arbitrary) threshold... static constexpr float kDimmingThreshold = 0.2f; Loading Loading @@ -1082,7 +1086,8 @@ void SkiaRenderEngine::drawLayersInternal( .undoPremultipliedAlpha = false, .requiresLinearEffect = requiresLinearEffect, .layerDimmingRatio = layerDimmingRatio, .outputDataSpace = runtimeEffectDataspace})); .outputDataSpace = display.outputDataspace, .fakeOutputDataspace = fakeDataspace})); } if (layer.disableBlending) { Loading
libs/renderengine/skia/SkiaRenderEngine.h +1 −0 Original line number Diff line number Diff line Loading @@ -157,6 +157,7 @@ private: bool requiresLinearEffect; float layerDimmingRatio; const ui::Dataspace outputDataSpace; const ui::Dataspace fakeOutputDataspace; }; sk_sp<SkShader> createRuntimeEffectShader(const RuntimeEffectShaderParameters&); Loading
libs/shaders/shaders.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -168,8 +168,8 @@ void generateOOTF(ui::Dataspace inputDataspace, ui::Dataspace outputDataspace, void generateOETF(std::string& shader) { // Only support gamma 2.2 for now shader.append(R"( float OETF(float3 linear) { return sign(linear) * pow(abs(linear), (1.0 / 2.2)); float3 OETF(float3 linear) { return sign(linear) * pow(abs(linear), float3(1.0 / 2.2)); } )"); } Loading
services/surfaceflinger/CompositionEngine/include/compositionengine/impl/planner/TexturePool.h +10 −7 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ public: TexturePool(renderengine::RenderEngine& renderEngine) : mRenderEngine(renderEngine), mEnabled(false) {} virtual ~TexturePool() = default; virtual ~TexturePool(); // Sets the display size for the texture pool. // This will trigger a reallocation for all remaining textures in the pool. Loading @@ -83,11 +83,10 @@ public: // be held by the pool. This is useful when the active display changes. void setEnabled(bool enable); void dump(std::string& out) const; void dump(std::string& out) const EXCLUDES(mMutex); protected: // Proteted visibility so that they can be used for testing const static constexpr size_t kMinPoolSize = 3; const static constexpr size_t kMaxPoolSize = 4; struct Entry { Loading @@ -96,16 +95,20 @@ protected: }; std::deque<Entry> mPool; std::future<std::shared_ptr<renderengine::ExternalTexture>> mGenTextureFuture; private: std::shared_ptr<renderengine::ExternalTexture> genTexture(); std::shared_ptr<renderengine::ExternalTexture> genTexture(ui::Size size); // Returns a previously borrowed texture to the pool. void returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& texture, const sp<Fence>& fence); void allocatePool(); renderengine::RenderEngine& mRenderEngine; ui::Size mSize; void genTextureAsyncIfNeeded() REQUIRES(mMutex); void resetPool() REQUIRES(mMutex); renderengine::RenderEngine& mRenderEngine GUARDED_BY(mRenderEngineMutex); ui::Size mSize GUARDED_BY(mMutex); bool mEnabled; mutable std::mutex mMutex; mutable std::mutex mRenderEngineMutex; }; } // namespace android::compositionengine::impl::planner
services/surfaceflinger/CompositionEngine/src/planner/TexturePool.cpp +50 −14 Original line number Diff line number Diff line Loading @@ -25,31 +25,61 @@ namespace android::compositionengine::impl::planner { void TexturePool::allocatePool() { TexturePool::~TexturePool() { if (mGenTextureFuture.valid()) { mGenTextureFuture.get(); } } void TexturePool::resetPool() { if (mGenTextureFuture.valid()) { mGenTextureFuture.get(); } mPool.clear(); if (mEnabled && mSize.isValid()) { mPool.resize(kMinPoolSize); std::generate_n(mPool.begin(), kMinPoolSize, [&]() { return Entry{genTexture(), nullptr}; }); genTextureAsyncIfNeeded(); } // Generate a new texture asynchronously so it will not require allocation on the main // thread. void TexturePool::genTextureAsyncIfNeeded() { if (mEnabled && mSize.isValid() && !mGenTextureFuture.valid()) { mGenTextureFuture = std::async( std::launch::async, [&](ui::Size size) { return genTexture(size); }, mSize); } } void TexturePool::setDisplaySize(ui::Size size) { std::lock_guard lock(mMutex); if (mSize == size) { return; } mSize = size; allocatePool(); resetPool(); } std::shared_ptr<TexturePool::AutoTexture> TexturePool::borrowTexture() { if (mPool.empty()) { return std::make_shared<AutoTexture>(*this, genTexture(), nullptr); std::lock_guard lock(mMutex); std::shared_ptr<TexturePool::AutoTexture> tex; if (mGenTextureFuture.valid()) { tex = std::make_shared<AutoTexture>(*this, mGenTextureFuture.get(), nullptr); } else { tex = std::make_shared<AutoTexture>(*this, genTexture(mSize), nullptr); } // Speculatively generate a new texture, so that the next call does not need // to wait for allocation. genTextureAsyncIfNeeded(); return tex; } const auto entry = mPool.front(); mPool.pop_front(); if (mPool.empty()) { std::lock_guard lock(mMutex); // Similiarly generate a new texture when lending out the last entry, so that // the next call does not need to wait for allocation. genTextureAsyncIfNeeded(); } return std::make_shared<AutoTexture>(*this, entry.texture, entry.fence); } Loading @@ -60,6 +90,8 @@ void TexturePool::returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& return; } std::lock_guard lock(mMutex); // Or the texture on the floor if the pool is no longer tracking textures of the same size. if (static_cast<int32_t>(texture->getBuffer()->getWidth()) != mSize.getWidth() || static_cast<int32_t>(texture->getBuffer()->getHeight()) != mSize.getHeight()) { Loading @@ -80,13 +112,14 @@ void TexturePool::returnTexture(std::shared_ptr<renderengine::ExternalTexture>&& mPool.push_back({std::move(texture), fence}); } std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture() { LOG_ALWAYS_FATAL_IF(!mSize.isValid(), "Attempted to generate texture with invalid size"); std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture(ui::Size size) { std::lock_guard lock(mRenderEngineMutex); LOG_ALWAYS_FATAL_IF(!size.isValid(), "Attempted to generate texture with invalid size"); return std::make_shared< renderengine::impl:: ExternalTexture>(sp<GraphicBuffer>:: make(static_cast<uint32_t>(mSize.getWidth()), static_cast<uint32_t>(mSize.getHeight()), make(static_cast<uint32_t>(size.getWidth()), static_cast<uint32_t>(size.getHeight()), HAL_PIXEL_FORMAT_RGBA_8888, 1U, static_cast<uint64_t>( GraphicBuffer::USAGE_HW_RENDER | Loading @@ -100,10 +133,13 @@ std::shared_ptr<renderengine::ExternalTexture> TexturePool::genTexture() { void TexturePool::setEnabled(bool enabled) { mEnabled = enabled; allocatePool(); std::lock_guard lock(mMutex); resetPool(); } void TexturePool::dump(std::string& out) const { std::lock_guard lock(mMutex); base::StringAppendF(&out, "TexturePool (%s) has %zu buffers of size [%" PRId32 ", %" PRId32 "]\n", mEnabled ? "enabled" : "disabled", mPool.size(), mSize.width, mSize.height); Loading