1*38e8c45fSAndroid Build Coastguard Worker /* 2*38e8c45fSAndroid Build Coastguard Worker * Copyright 2020 The Android Open Source Project 3*38e8c45fSAndroid Build Coastguard Worker * 4*38e8c45fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*38e8c45fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*38e8c45fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*38e8c45fSAndroid Build Coastguard Worker * 8*38e8c45fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*38e8c45fSAndroid Build Coastguard Worker * 10*38e8c45fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*38e8c45fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*38e8c45fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*38e8c45fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*38e8c45fSAndroid Build Coastguard Worker * limitations under the License. 15*38e8c45fSAndroid Build Coastguard Worker */ 16*38e8c45fSAndroid Build Coastguard Worker 17*38e8c45fSAndroid Build Coastguard Worker #ifndef SF_SKIARENDERENGINE_H_ 18*38e8c45fSAndroid Build Coastguard Worker #define SF_SKIARENDERENGINE_H_ 19*38e8c45fSAndroid Build Coastguard Worker 20*38e8c45fSAndroid Build Coastguard Worker #include <renderengine/RenderEngine.h> 21*38e8c45fSAndroid Build Coastguard Worker 22*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h> 23*38e8c45fSAndroid Build Coastguard Worker #include <include/core/SkImageInfo.h> 24*38e8c45fSAndroid Build Coastguard Worker #include <include/core/SkSurface.h> 25*38e8c45fSAndroid Build Coastguard Worker #include <include/gpu/ganesh/GrBackendSemaphore.h> 26*38e8c45fSAndroid Build Coastguard Worker #include <include/gpu/ganesh/GrContextOptions.h> 27*38e8c45fSAndroid Build Coastguard Worker #include <renderengine/ExternalTexture.h> 28*38e8c45fSAndroid Build Coastguard Worker #include <renderengine/RenderEngine.h> 29*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h> 30*38e8c45fSAndroid Build Coastguard Worker 31*38e8c45fSAndroid Build Coastguard Worker #include <memory> 32*38e8c45fSAndroid Build Coastguard Worker #include <mutex> 33*38e8c45fSAndroid Build Coastguard Worker #include <unordered_map> 34*38e8c45fSAndroid Build Coastguard Worker 35*38e8c45fSAndroid Build Coastguard Worker #include "AutoBackendTexture.h" 36*38e8c45fSAndroid Build Coastguard Worker #include "android-base/macros.h" 37*38e8c45fSAndroid Build Coastguard Worker #include "compat/SkiaGpuContext.h" 38*38e8c45fSAndroid Build Coastguard Worker #include "debug/SkiaCapture.h" 39*38e8c45fSAndroid Build Coastguard Worker #include "filters/BlurFilter.h" 40*38e8c45fSAndroid Build Coastguard Worker #include "filters/EdgeExtensionShaderFactory.h" 41*38e8c45fSAndroid Build Coastguard Worker #include "filters/LinearEffect.h" 42*38e8c45fSAndroid Build Coastguard Worker #include "filters/LutShader.h" 43*38e8c45fSAndroid Build Coastguard Worker #include "filters/StretchShaderFactory.h" 44*38e8c45fSAndroid Build Coastguard Worker 45*38e8c45fSAndroid Build Coastguard Worker class SkData; 46*38e8c45fSAndroid Build Coastguard Worker 47*38e8c45fSAndroid Build Coastguard Worker struct SkPoint3; 48*38e8c45fSAndroid Build Coastguard Worker 49*38e8c45fSAndroid Build Coastguard Worker namespace android { 50*38e8c45fSAndroid Build Coastguard Worker 51*38e8c45fSAndroid Build Coastguard Worker namespace renderengine { 52*38e8c45fSAndroid Build Coastguard Worker 53*38e8c45fSAndroid Build Coastguard Worker class Mesh; 54*38e8c45fSAndroid Build Coastguard Worker class Texture; 55*38e8c45fSAndroid Build Coastguard Worker 56*38e8c45fSAndroid Build Coastguard Worker namespace skia { 57*38e8c45fSAndroid Build Coastguard Worker 58*38e8c45fSAndroid Build Coastguard Worker class BlurFilter; 59*38e8c45fSAndroid Build Coastguard Worker 60*38e8c45fSAndroid Build Coastguard Worker class SkiaRenderEngine : public RenderEngine { 61*38e8c45fSAndroid Build Coastguard Worker public: 62*38e8c45fSAndroid Build Coastguard Worker static std::unique_ptr<SkiaRenderEngine> create(const RenderEngineCreationArgs& args); 63*38e8c45fSAndroid Build Coastguard Worker SkiaRenderEngine(Threaded, PixelFormat pixelFormat, BlurAlgorithm); 64*38e8c45fSAndroid Build Coastguard Worker ~SkiaRenderEngine() override; 65*38e8c45fSAndroid Build Coastguard Worker 66*38e8c45fSAndroid Build Coastguard Worker std::future<void> primeCache(PrimeCacheConfig config) override final; 67*38e8c45fSAndroid Build Coastguard Worker void cleanupPostRender() override final; supportsBackgroundBlur()68*38e8c45fSAndroid Build Coastguard Worker bool supportsBackgroundBlur() override final { 69*38e8c45fSAndroid Build Coastguard Worker return mBlurFilter != nullptr; 70*38e8c45fSAndroid Build Coastguard Worker } 71*38e8c45fSAndroid Build Coastguard Worker void onActiveDisplaySizeChanged(ui::Size size) override final; 72*38e8c45fSAndroid Build Coastguard Worker int reportShadersCompiled(); 73*38e8c45fSAndroid Build Coastguard Worker 74*38e8c45fSAndroid Build Coastguard Worker virtual void setEnableTracing(bool tracingEnabled) override final; 75*38e8c45fSAndroid Build Coastguard Worker 76*38e8c45fSAndroid Build Coastguard Worker void useProtectedContext(bool useProtectedContext) override; supportsProtectedContent()77*38e8c45fSAndroid Build Coastguard Worker bool supportsProtectedContent() const override { 78*38e8c45fSAndroid Build Coastguard Worker return supportsProtectedContentImpl(); 79*38e8c45fSAndroid Build Coastguard Worker } 80*38e8c45fSAndroid Build Coastguard Worker void ensureContextsCreated(); 81*38e8c45fSAndroid Build Coastguard Worker 82*38e8c45fSAndroid Build Coastguard Worker protected: 83*38e8c45fSAndroid Build Coastguard Worker // This is so backends can stop the generic rendering state first before cleaning up 84*38e8c45fSAndroid Build Coastguard Worker // backend-specific state. SkiaGpuContexts are invalid after invocation. 85*38e8c45fSAndroid Build Coastguard Worker void finishRenderingAndAbandonContexts(); 86*38e8c45fSAndroid Build Coastguard Worker 87*38e8c45fSAndroid Build Coastguard Worker // Functions that a given backend (GLES, Vulkan) must implement 88*38e8c45fSAndroid Build Coastguard Worker using Contexts = std::pair<unique_ptr<SkiaGpuContext>, unique_ptr<SkiaGpuContext>>; 89*38e8c45fSAndroid Build Coastguard Worker virtual Contexts createContexts() = 0; 90*38e8c45fSAndroid Build Coastguard Worker virtual bool supportsProtectedContentImpl() const = 0; 91*38e8c45fSAndroid Build Coastguard Worker virtual bool useProtectedContextImpl(GrProtected isProtected) = 0; 92*38e8c45fSAndroid Build Coastguard Worker virtual void waitFence(SkiaGpuContext* context, base::borrowed_fd fenceFd) = 0; 93*38e8c45fSAndroid Build Coastguard Worker virtual base::unique_fd flushAndSubmit(SkiaGpuContext* context, 94*38e8c45fSAndroid Build Coastguard Worker sk_sp<SkSurface> dstSurface) = 0; 95*38e8c45fSAndroid Build Coastguard Worker virtual void appendBackendSpecificInfoToDump(std::string& result) = 0; 96*38e8c45fSAndroid Build Coastguard Worker 97*38e8c45fSAndroid Build Coastguard Worker size_t getMaxTextureSize() const override final; 98*38e8c45fSAndroid Build Coastguard Worker size_t getMaxViewportDims() const override final; 99*38e8c45fSAndroid Build Coastguard Worker // TODO: b/293371537 - Return reference instead of pointer? (Cleanup) 100*38e8c45fSAndroid Build Coastguard Worker SkiaGpuContext* getActiveContext(); 101*38e8c45fSAndroid Build Coastguard Worker isProtected()102*38e8c45fSAndroid Build Coastguard Worker bool isProtected() const { return mInProtectedContext; } 103*38e8c45fSAndroid Build Coastguard Worker 104*38e8c45fSAndroid Build Coastguard Worker // Implements PersistentCache as a way to monitor what SkSL shaders Skia has 105*38e8c45fSAndroid Build Coastguard Worker // cached. 106*38e8c45fSAndroid Build Coastguard Worker class SkSLCacheMonitor : public GrContextOptions::PersistentCache { 107*38e8c45fSAndroid Build Coastguard Worker public: 108*38e8c45fSAndroid Build Coastguard Worker SkSLCacheMonitor() = default; 109*38e8c45fSAndroid Build Coastguard Worker ~SkSLCacheMonitor() override = default; 110*38e8c45fSAndroid Build Coastguard Worker 111*38e8c45fSAndroid Build Coastguard Worker sk_sp<SkData> load(const SkData& key) override; 112*38e8c45fSAndroid Build Coastguard Worker 113*38e8c45fSAndroid Build Coastguard Worker void store(const SkData& key, const SkData& data, const SkString& description) override; 114*38e8c45fSAndroid Build Coastguard Worker shadersCachedSinceLastCall()115*38e8c45fSAndroid Build Coastguard Worker int shadersCachedSinceLastCall() { 116*38e8c45fSAndroid Build Coastguard Worker const int shadersCachedSinceLastCall = mShadersCachedSinceLastCall; 117*38e8c45fSAndroid Build Coastguard Worker mShadersCachedSinceLastCall = 0; 118*38e8c45fSAndroid Build Coastguard Worker return shadersCachedSinceLastCall; 119*38e8c45fSAndroid Build Coastguard Worker } 120*38e8c45fSAndroid Build Coastguard Worker totalShadersCompiled()121*38e8c45fSAndroid Build Coastguard Worker int totalShadersCompiled() const { return mTotalShadersCompiled; } 122*38e8c45fSAndroid Build Coastguard Worker 123*38e8c45fSAndroid Build Coastguard Worker private: 124*38e8c45fSAndroid Build Coastguard Worker int mShadersCachedSinceLastCall = 0; 125*38e8c45fSAndroid Build Coastguard Worker int mTotalShadersCompiled = 0; 126*38e8c45fSAndroid Build Coastguard Worker }; 127*38e8c45fSAndroid Build Coastguard Worker 128*38e8c45fSAndroid Build Coastguard Worker SkSLCacheMonitor mSkSLCacheMonitor; 129*38e8c45fSAndroid Build Coastguard Worker 130*38e8c45fSAndroid Build Coastguard Worker private: 131*38e8c45fSAndroid Build Coastguard Worker void mapExternalTextureBuffer(const sp<GraphicBuffer>& buffer, 132*38e8c45fSAndroid Build Coastguard Worker bool isRenderable) override final; 133*38e8c45fSAndroid Build Coastguard Worker void unmapExternalTextureBuffer(sp<GraphicBuffer>&& buffer) override final; 134*38e8c45fSAndroid Build Coastguard Worker bool canSkipPostRenderCleanup() const override final; 135*38e8c45fSAndroid Build Coastguard Worker 136*38e8c45fSAndroid Build Coastguard Worker std::shared_ptr<AutoBackendTexture::LocalRef> getOrCreateBackendTexture( 137*38e8c45fSAndroid Build Coastguard Worker const sp<GraphicBuffer>& buffer, bool isOutputBuffer) REQUIRES(mRenderingMutex); 138*38e8c45fSAndroid Build Coastguard Worker void initCanvas(SkCanvas* canvas, const DisplaySettings& display); 139*38e8c45fSAndroid Build Coastguard Worker void drawShadow(SkCanvas* canvas, const SkRRect& casterRRect, 140*38e8c45fSAndroid Build Coastguard Worker const ShadowSettings& shadowSettings); 141*38e8c45fSAndroid Build Coastguard Worker void drawLayersInternal(const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, 142*38e8c45fSAndroid Build Coastguard Worker const DisplaySettings& display, 143*38e8c45fSAndroid Build Coastguard Worker const std::vector<LayerSettings>& layers, 144*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& buffer, 145*38e8c45fSAndroid Build Coastguard Worker base::unique_fd&& bufferFence) override final; 146*38e8c45fSAndroid Build Coastguard Worker void drawGainmapInternal(const std::shared_ptr<std::promise<FenceResult>>&& resultPromise, 147*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& sdr, 148*38e8c45fSAndroid Build Coastguard Worker base::borrowed_fd&& sdrFence, 149*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& hdr, 150*38e8c45fSAndroid Build Coastguard Worker base::borrowed_fd&& hdrFence, float hdrSdrRatio, 151*38e8c45fSAndroid Build Coastguard Worker ui::Dataspace dataspace, 152*38e8c45fSAndroid Build Coastguard Worker const std::shared_ptr<ExternalTexture>& gainmap) override final; 153*38e8c45fSAndroid Build Coastguard Worker 154*38e8c45fSAndroid Build Coastguard Worker void dump(std::string& result) override final; 155*38e8c45fSAndroid Build Coastguard Worker 156*38e8c45fSAndroid Build Coastguard Worker // If requiresLinearEffect is true or the layer has a stretchEffect a new shader is returned. 157*38e8c45fSAndroid Build Coastguard Worker // Otherwise it returns the input shader. 158*38e8c45fSAndroid Build Coastguard Worker struct RuntimeEffectShaderParameters { 159*38e8c45fSAndroid Build Coastguard Worker sk_sp<SkShader> shader; 160*38e8c45fSAndroid Build Coastguard Worker const LayerSettings& layer; 161*38e8c45fSAndroid Build Coastguard Worker const DisplaySettings& display; 162*38e8c45fSAndroid Build Coastguard Worker bool undoPremultipliedAlpha; 163*38e8c45fSAndroid Build Coastguard Worker bool requiresLinearEffect; 164*38e8c45fSAndroid Build Coastguard Worker float layerDimmingRatio; 165*38e8c45fSAndroid Build Coastguard Worker const ui::Dataspace outputDataSpace; 166*38e8c45fSAndroid Build Coastguard Worker const ui::Dataspace fakeOutputDataspace; 167*38e8c45fSAndroid Build Coastguard Worker const SkRect& imageBounds; 168*38e8c45fSAndroid Build Coastguard Worker }; 169*38e8c45fSAndroid Build Coastguard Worker sk_sp<SkShader> createRuntimeEffectShader(const RuntimeEffectShaderParameters&); 170*38e8c45fSAndroid Build Coastguard Worker 171*38e8c45fSAndroid Build Coastguard Worker const PixelFormat mDefaultPixelFormat; 172*38e8c45fSAndroid Build Coastguard Worker 173*38e8c45fSAndroid Build Coastguard Worker // Identifier used for various mappings of layers to various 174*38e8c45fSAndroid Build Coastguard Worker // textures or shaders 175*38e8c45fSAndroid Build Coastguard Worker using GraphicBufferId = uint64_t; 176*38e8c45fSAndroid Build Coastguard Worker 177*38e8c45fSAndroid Build Coastguard Worker // Number of external holders of ExternalTexture references, per GraphicBuffer ID. 178*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<GraphicBufferId, int32_t> mGraphicBufferExternalRefs 179*38e8c45fSAndroid Build Coastguard Worker GUARDED_BY(mRenderingMutex); 180*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<GraphicBufferId, std::shared_ptr<AutoBackendTexture::LocalRef>> mTextureCache 181*38e8c45fSAndroid Build Coastguard Worker GUARDED_BY(mRenderingMutex); 182*38e8c45fSAndroid Build Coastguard Worker std::unordered_map<shaders::LinearEffect, sk_sp<SkRuntimeEffect>, shaders::LinearEffectHasher> 183*38e8c45fSAndroid Build Coastguard Worker mRuntimeEffects; 184*38e8c45fSAndroid Build Coastguard Worker AutoBackendTexture::CleanupManager mTextureCleanupMgr GUARDED_BY(mRenderingMutex); 185*38e8c45fSAndroid Build Coastguard Worker 186*38e8c45fSAndroid Build Coastguard Worker StretchShaderFactory mStretchShaderFactory; 187*38e8c45fSAndroid Build Coastguard Worker EdgeExtensionShaderFactory mEdgeExtensionShaderFactory; 188*38e8c45fSAndroid Build Coastguard Worker LutShader mLutShader; 189*38e8c45fSAndroid Build Coastguard Worker 190*38e8c45fSAndroid Build Coastguard Worker sp<Fence> mLastDrawFence; 191*38e8c45fSAndroid Build Coastguard Worker BlurFilter* mBlurFilter = nullptr; 192*38e8c45fSAndroid Build Coastguard Worker 193*38e8c45fSAndroid Build Coastguard Worker // Object to capture commands send to Skia. 194*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<SkiaCapture> mCapture; 195*38e8c45fSAndroid Build Coastguard Worker 196*38e8c45fSAndroid Build Coastguard Worker // Mutex guarding rendering operations, so that internal state related to 197*38e8c45fSAndroid Build Coastguard Worker // rendering that is potentially modified by multiple threads is guaranteed thread-safe. 198*38e8c45fSAndroid Build Coastguard Worker mutable std::mutex mRenderingMutex; 199*38e8c45fSAndroid Build Coastguard Worker 200*38e8c45fSAndroid Build Coastguard Worker // Graphics context used for creating surfaces and submitting commands 201*38e8c45fSAndroid Build Coastguard Worker unique_ptr<SkiaGpuContext> mContext; 202*38e8c45fSAndroid Build Coastguard Worker // Same as above, but for protected content (eg. DRM) 203*38e8c45fSAndroid Build Coastguard Worker unique_ptr<SkiaGpuContext> mProtectedContext; 204*38e8c45fSAndroid Build Coastguard Worker bool mInProtectedContext = false; 205*38e8c45fSAndroid Build Coastguard Worker }; 206*38e8c45fSAndroid Build Coastguard Worker 207*38e8c45fSAndroid Build Coastguard Worker } // namespace skia 208*38e8c45fSAndroid Build Coastguard Worker } // namespace renderengine 209*38e8c45fSAndroid Build Coastguard Worker } // namespace android 210*38e8c45fSAndroid Build Coastguard Worker 211*38e8c45fSAndroid Build Coastguard Worker #endif /* SF_GLESRENDERENGINE_H_ */ 212