/* * Copyright 2020 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. */ #ifndef SF_SKIARENDERENGINE_H_ #define SF_SKIARENDERENGINE_H_ #include #include #include #include #include #include #include #include #include #include #include #include "AutoBackendTexture.h" #include "GrContextOptions.h" #include "SkImageInfo.h" #include "SkiaRenderEngine.h" #include "android-base/macros.h" #include "debug/SkiaCapture.h" #include "filters/BlurFilter.h" #include "filters/LinearEffect.h" #include "filters/StretchShaderFactory.h" #ifdef MTK_IN_DISPLAY_FINGERPRINT #include "../mediatek/SkiaDitherEffect.h" #endif class SkData; struct SkPoint3; namespace android { namespace renderengine { class Mesh; class Texture; namespace skia { class BlurFilter; #ifdef MTK_DUMP_SKIA_GL_SHADER struct ShaderUniformInfo { int32_t location; std::string name; std::string type; int32_t size; std::string value; ShaderUniformInfo() : name(), type(), value() {} }; struct ShaderInfo { int32_t program; std::map uniforms; std::string v_shader; std::string f_shader; ui::Dataspace dataspace; uint32_t colorRange; ShaderInfo() : program(0), uniforms(), v_shader(), f_shader(), dataspace(ui::Dataspace::UNKNOWN), colorRange(0) {} }; #endif class SkiaRenderEngine : public RenderEngine { public: static std::unique_ptr create(const RenderEngineCreationArgs& args); SkiaRenderEngine(RenderEngineType type, PixelFormat pixelFormat, bool useColorManagement, bool supportsBackgroundBlur); ~SkiaRenderEngine() override; std::future primeCache() override final; void cleanupPostRender() override final; void cleanFramebufferCache() override final{ } bool supportsBackgroundBlur() override final { return mBlurFilter != nullptr; } #ifdef MTK_SF_PQ_MANAGEMENT void setDeviceInfo(const bool is_primary) override; #endif void onActiveDisplaySizeChanged(ui::Size size) override final; int reportShadersCompiled(); virtual void genTextures(size_t /*count*/, uint32_t* /*names*/) override final{}; virtual void deleteTextures(size_t /*count*/, uint32_t const* /*names*/) override final{}; virtual void setEnableTracing(bool tracingEnabled) override final; void useProtectedContext(bool useProtectedContext) override; bool supportsProtectedContent() const override { return supportsProtectedContentImpl(); } void ensureGrContextsCreated(); protected: #ifdef MTK_IN_DISPLAY_FINGERPRINT SkiaDitherEffect * mSkiaDitherEffect = nullptr; #endif #ifdef MTK_DUMP_SKIA_GL_SHADER bool mDumpShader = false; std::map shaderInfo; virtual bool tryGetShaderInfo(const std::string&, ui::Dataspace, uint32_t) { return false; }; virtual void mtkDumpShader(const android::renderengine::LayerSettings&, ui::Dataspace) {}; #endif // This is so backends can stop the generic rendering state first before // cleaning up backend-specific state void finishRenderingAndAbandonContext(); // Functions that a given backend (GLES, Vulkan) must implement using Contexts = std::pair, sk_sp>; virtual Contexts createDirectContexts(const GrContextOptions& options) = 0; virtual bool supportsProtectedContentImpl() const = 0; virtual bool useProtectedContextImpl(GrProtected isProtected) = 0; virtual void waitFence(GrDirectContext* grContext, base::borrowed_fd fenceFd) = 0; virtual base::unique_fd flushAndSubmit(GrDirectContext* context) = 0; virtual void appendBackendSpecificInfoToDump(std::string& result) = 0; size_t getMaxTextureSize() const override final; size_t getMaxViewportDims() const override final; GrDirectContext* getActiveGrContext(); bool isProtected() const { return mInProtectedContext; } // Implements PersistentCache as a way to monitor what SkSL shaders Skia has // cached. class SkSLCacheMonitor : public GrContextOptions::PersistentCache { public: SkSLCacheMonitor() = default; ~SkSLCacheMonitor() override = default; sk_sp load(const SkData& key) override; void store(const SkData& key, const SkData& data, const SkString& description) override; int shadersCachedSinceLastCall() { const int shadersCachedSinceLastCall = mShadersCachedSinceLastCall; mShadersCachedSinceLastCall = 0; return shadersCachedSinceLastCall; } int totalShadersCompiled() const { return mTotalShadersCompiled; } private: int mShadersCachedSinceLastCall = 0; int mTotalShadersCompiled = 0; }; private: #ifdef MTK_SKIP_SKIA_EXTERNAL_TEXTURE_CACHE bool mSkipExternalTexture; bool isSkipExternalTexureCache(const sp& buffer); #endif #ifdef MTK_SF_PQ_MANAGEMENT bool getAndClearDeviceInfo(); void updatePQFlag(const sp& buffer, const bool isHDR, const bool is_primary); #endif void mapExternalTextureBuffer(const sp& buffer, bool isRenderable) override final; void unmapExternalTextureBuffer(sp&& buffer) override final; bool canSkipPostRenderCleanup() const override final; std::shared_ptr getOrCreateBackendTexture( const sp& buffer, bool isOutputBuffer) REQUIRES(mRenderingMutex); #ifdef MTK_SKIP_SKIA_EXTERNAL_TEXTURE_CACHE std::shared_ptr getOrCreateBackendTexture( const sp& buffer, bool isOutputBuffer, bool * outSkipUpdate) REQUIRES(mRenderingMutex); #endif void initCanvas(SkCanvas* canvas, const DisplaySettings& display); void drawShadow(SkCanvas* canvas, const SkRRect& casterRRect, const ShadowSettings& shadowSettings); void drawLayersInternal(const std::shared_ptr>&& resultPromise, const DisplaySettings& display, const std::vector& layers, const std::shared_ptr& buffer, const bool useFramebufferCache, base::unique_fd&& bufferFence) override final; void dump(std::string& result) override final; // If requiresLinearEffect is true or the layer has a stretchEffect a new shader is returned. // Otherwise it returns the input shader. struct RuntimeEffectShaderParameters { sk_sp shader; const LayerSettings& layer; const DisplaySettings& display; bool undoPremultipliedAlpha; bool requiresLinearEffect; float layerDimmingRatio; const ui::Dataspace outputDataSpace; }; sk_sp createRuntimeEffectShader(const RuntimeEffectShaderParameters&); const PixelFormat mDefaultPixelFormat; const bool mUseColorManagement; // Identifier used for various mappings of layers to various // textures or shaders using GraphicBufferId = uint64_t; #ifdef MTK_SF_PQ_MANAGEMENT //Identifier of if the RenderEngine Output Device is main Primary or 2nd Display bool mIsPrimary; #endif // Number of external holders of ExternalTexture references, per GraphicBuffer ID. std::unordered_map mGraphicBufferExternalRefs GUARDED_BY(mRenderingMutex); // For GL, this cache is shared between protected and unprotected contexts. For Vulkan, it is // only used for the unprotected context, because Vulkan does not allow sharing between // contexts, and protected is less common. std::unordered_map> mTextureCache GUARDED_BY(mRenderingMutex); std::unordered_map, shaders::LinearEffectHasher> mRuntimeEffects; AutoBackendTexture::CleanupManager mTextureCleanupMgr GUARDED_BY(mRenderingMutex); StretchShaderFactory mStretchShaderFactory; sp mLastDrawFence; BlurFilter* mBlurFilter = nullptr; // Object to capture commands send to Skia. std::unique_ptr mCapture; // Mutex guarding rendering operations, so that internal state related to // rendering that is potentially modified by multiple threads is guaranteed thread-safe. mutable std::mutex mRenderingMutex; SkSLCacheMonitor mSkSLCacheMonitor; // Graphics context used for creating surfaces and submitting commands sk_sp mGrContext; // Same as above, but for protected content (eg. DRM) sk_sp mProtectedGrContext; bool mInProtectedContext = false; }; } // namespace skia } // namespace renderengine } // namespace android #endif /* SF_GLESRENDERENGINE_H_ */