From 60919a0a7e0a7069bd17980fb9a4885c7db4ca19 Mon Sep 17 00:00:00 2001 From: domrjchen Date: Fri, 11 Feb 2022 14:17:33 +0800 Subject: [PATCH] Add ResourceCache and ProgramCache classes. --- src/platform/android/GPUDrawable.cpp | 1 + src/platform/android/VideoSurface.cpp | 4 +- src/platform/cocoa/private/TraceImage.mm | 1 + src/platform/web/GPUDrawable.cpp | 1 + src/platform/win/GPUDrawable.cpp | 1 + src/rendering/caches/RenderCache.cpp | 4 +- src/rendering/graphics/Glyph.h | 2 +- src/rendering/graphics/Modifier.cpp | 1 + src/rendering/graphics/Picture.cpp | 2 +- src/rendering/graphics/TextureProxy.h | 2 +- src/rendering/utils/MemoryCalculator.cpp | 1 + test/framework/utils/LzmaUtil.h | 1 + tgfx/include/core/Bitmap.h | 4 +- tgfx/include/core/Blend.h | 2 - tgfx/include/core/Data.h | 3 +- tgfx/include/core/Font.h | 2 +- tgfx/include/core/Image.h | 7 +- tgfx/include/core/ImageInfo.h | 1 - tgfx/include/core/Mask.h | 6 +- tgfx/include/core/Path.h | 3 +- tgfx/include/core/PathEffect.h | 2 +- tgfx/include/core/PathMeasure.h | 2 +- tgfx/include/core/PixelBuffer.h | 2 +- tgfx/include/core/Stream.h | 2 +- tgfx/include/core/TextBlob.h | 4 +- tgfx/include/core/Typeface.h | 4 +- tgfx/include/gpu/Context.h | 69 +++--- tgfx/include/gpu/Device.h | 3 +- tgfx/include/gpu/Resource.h | 7 +- tgfx/include/gpu/Texture.h | 3 +- tgfx/{src => include}/gpu/opengl/GLDevice.h | 3 + tgfx/include/gpu/opengl/webgl/WebGLDevice.h | 1 - .../base => tgfx/src/core}/utils/BytesKey.cpp | 2 +- {src/base => tgfx/src/core}/utils/BytesKey.h | 0 .../vectors/coregraphics/CGScalerContext.cpp | 1 + .../core/vectors/freetype/FTScalerContext.cpp | 1 + tgfx/src/gpu/AlphaFragmentProcessor.cpp | 1 + tgfx/src/gpu/ConstColorProcessor.cpp | 1 + tgfx/src/gpu/Context.cpp | 223 ++---------------- tgfx/src/gpu/Device.cpp | 1 + tgfx/src/gpu/EllipseGeometryProcessor.cpp | 1 + tgfx/src/gpu/EmptyXferProcessor.cpp | 1 + tgfx/src/gpu/GradientCache.h | 2 +- tgfx/src/gpu/GradientShader.cpp | 3 +- tgfx/src/gpu/Pipeline.cpp | 1 + tgfx/src/gpu/PorterDuffXferProcessor.cpp | 1 + tgfx/src/gpu/Processor.h | 2 +- tgfx/src/gpu/Program.h | 4 +- tgfx/src/gpu/ProgramCache.cpp | 69 ++++++ tgfx/src/gpu/ProgramCache.h | 55 +++++ .../gpu/QuadPerEdgeAAGeometryProcessor.cpp | 1 + tgfx/src/gpu/ResourceCache.cpp | 190 +++++++++++++++ tgfx/src/gpu/ResourceCache.h | 72 ++++++ tgfx/src/gpu/TextureFragmentProcessor.cpp | 1 + tgfx/src/gpu/TextureMaskFragmentProcessor.cpp | 1 + tgfx/src/gpu/TextureSampler.h | 2 +- tgfx/src/gpu/Window.cpp | 3 +- tgfx/src/gpu/XferProcessor.h | 2 +- tgfx/src/gpu/YUVTextureFragmentProcessor.cpp | 1 + .../gpu/gradients/ClampedGradientEffect.cpp | 1 + .../DualIntervalGradientColorizer.cpp | 1 + .../gpu/gradients/LinearGradientLayout.cpp | 1 + .../gpu/gradients/RadialGradientLayout.cpp | 1 + .../SingleIntervalGradientColorizer.cpp | 1 + .../gradients/TextureGradientColorizer.cpp | 1 + .../UnrolledBinaryGradientColorizer.cpp | 1 + tgfx/src/gpu/opengl/GLBuffer.cpp | 4 +- tgfx/src/gpu/opengl/GLContext.cpp | 4 +- tgfx/src/gpu/opengl/GLDevice.cpp | 4 +- tgfx/src/gpu/opengl/GLDrawer.cpp | 8 +- .../gpu/opengl/GLEllipseGeometryProcessor.cpp | 2 +- tgfx/src/gpu/opengl/GLTexture.cpp | 4 +- tgfx/src/gpu/opengl/GLYUVTexture.cpp | 7 +- tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm | 7 +- .../gpu/opengl/eagl/EAGLHardwareTexture.mm | 7 +- tgfx/src/gpu/opengl/eagl/EAGLWindow.mm | 4 +- tgfx/src/gpu/opengl/egl/EGLDevice.cpp | 1 + .../src/gpu/opengl/egl/EGLHardwareTexture.cpp | 9 +- tgfx/src/gpu/opengl/qt/QGLDevice.cpp | 1 + tgfx/src/gpu/opengl/webgl/WebGLDevice.cpp | 1 + tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp | 1 + 81 files changed, 549 insertions(+), 315 deletions(-) rename tgfx/{src => include}/gpu/opengl/GLDevice.h (97%) rename {src/base => tgfx/src/core}/utils/BytesKey.cpp (98%) rename {src/base => tgfx/src/core}/utils/BytesKey.h (100%) create mode 100644 tgfx/src/gpu/ProgramCache.cpp create mode 100644 tgfx/src/gpu/ProgramCache.h create mode 100644 tgfx/src/gpu/ResourceCache.cpp create mode 100644 tgfx/src/gpu/ResourceCache.h diff --git a/src/platform/android/GPUDrawable.cpp b/src/platform/android/GPUDrawable.cpp index e638023dbd..809bdd7c0e 100644 --- a/src/platform/android/GPUDrawable.cpp +++ b/src/platform/android/GPUDrawable.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "GPUDrawable.h" +#include "base/utils/Log.h" #include "gpu/Surface.h" namespace pag { diff --git a/src/platform/android/VideoSurface.cpp b/src/platform/android/VideoSurface.cpp index 503c077c38..c3059a8665 100644 --- a/src/platform/android/VideoSurface.cpp +++ b/src/platform/android/VideoSurface.cpp @@ -128,7 +128,7 @@ jobject VideoSurface::getOutputSurface(JNIEnv* env) const { bool VideoSurface::attachToContext(Context* context) { if (oesTexture) { - if (deviceID != context->getDevice()->uniqueID()) { + if (deviceID != context->device()->uniqueID()) { LOGE("VideoSurface::attachToGLContext(): VideoSurface has already attached to a Context!"); return false; } @@ -146,7 +146,7 @@ bool VideoSurface::attachToContext(Context* context) { } auto result = env->CallBooleanMethod(videoSurface.get(), VideoSurface_attachToGLContext, oesTexture->getGLInfo().id); - deviceID = context->getDevice()->uniqueID(); + deviceID = context->device()->uniqueID(); if (!result) { LOGE("VideoSurface::attachToGLContext(): failed to attached to a Surface!"); oesTexture = nullptr; diff --git a/src/platform/cocoa/private/TraceImage.mm b/src/platform/cocoa/private/TraceImage.mm index 7fa72787b5..979ac7fd44 100644 --- a/src/platform/cocoa/private/TraceImage.mm +++ b/src/platform/cocoa/private/TraceImage.mm @@ -18,6 +18,7 @@ #include "TraceImage.h" #include "PixelBufferUtils.h" +#include "base/utils/Log.h" #include "core/Bitmap.h" namespace pag { diff --git a/src/platform/web/GPUDrawable.cpp b/src/platform/web/GPUDrawable.cpp index 5fd2cccb6a..7b94b92867 100644 --- a/src/platform/web/GPUDrawable.cpp +++ b/src/platform/web/GPUDrawable.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "GPUDrawable.h" +#include "base/utils/Log.h" #include "gpu/Surface.h" #include "gpu/opengl/GLDefines.h" diff --git a/src/platform/win/GPUDrawable.cpp b/src/platform/win/GPUDrawable.cpp index c9c82c7470..a329b6ddaf 100644 --- a/src/platform/win/GPUDrawable.cpp +++ b/src/platform/win/GPUDrawable.cpp @@ -18,6 +18,7 @@ #include "GPUDrawable.h" #include +#include "base/utils/Log.h" #include "gpu/opengl/egl/EGLWindow.h" namespace pag { diff --git a/src/rendering/caches/RenderCache.cpp b/src/rendering/caches/RenderCache.cpp index b141541019..641999578b 100644 --- a/src/rendering/caches/RenderCache.cpp +++ b/src/rendering/caches/RenderCache.cpp @@ -177,13 +177,13 @@ void RenderCache::prepareFrame() { } void RenderCache::attachToContext(Context* current, bool forHitTest) { - if (deviceID > 0 && deviceID != current->getDevice()->uniqueID()) { + if (deviceID > 0 && deviceID != current->device()->uniqueID()) { // Context 改变需要清理内部所有缓存,这里用 uniqueID // 而不用指针比较,是因为指针析构后再创建可能会地址重合。 releaseAll(); } context = current; - deviceID = context->getDevice()->uniqueID(); + deviceID = context->device()->uniqueID(); hitTestOnly = forHitTest; if (hitTestOnly) { return; diff --git a/src/rendering/graphics/Glyph.h b/src/rendering/graphics/Glyph.h index 8d10fd8125..460d9f2f15 100644 --- a/src/rendering/graphics/Glyph.h +++ b/src/rendering/graphics/Glyph.h @@ -18,8 +18,8 @@ #pragma once -#include "base/utils/BytesKey.h" #include "core/Font.h" +#include "core/utils/BytesKey.h" #include "pag/types.h" namespace pag { diff --git a/src/rendering/graphics/Modifier.cpp b/src/rendering/graphics/Modifier.cpp index 05fd9d57ba..72c1a84568 100644 --- a/src/rendering/graphics/Modifier.cpp +++ b/src/rendering/graphics/Modifier.cpp @@ -19,6 +19,7 @@ #include "Modifier.h" #include "Graphic.h" #include "base/utils/MatrixUtil.h" +#include "base/utils/UniqueID.h" #include "core/Blend.h" #include "gpu/Surface.h" diff --git a/src/rendering/graphics/Picture.cpp b/src/rendering/graphics/Picture.cpp index e225c9a750..4bd34a0928 100644 --- a/src/rendering/graphics/Picture.cpp +++ b/src/rendering/graphics/Picture.cpp @@ -441,7 +441,7 @@ class BackendTextureProxy : public TextureProxy { void* sharedContext = nullptr; bool checkContext(Context* context) const { - auto glDevice = static_cast(context->getDevice()); + auto glDevice = static_cast(context->device()); if (!glDevice->sharableWith(sharedContext)) { LOGE( "A Graphic which made from a texture can not be drawn on to a PAGSurface" diff --git a/src/rendering/graphics/TextureProxy.h b/src/rendering/graphics/TextureProxy.h index 0377e33cf9..54016c2ac6 100644 --- a/src/rendering/graphics/TextureProxy.h +++ b/src/rendering/graphics/TextureProxy.h @@ -18,7 +18,7 @@ #pragma once -#include "gpu/Context.h" +#include "gpu/Texture.h" namespace pag { class RenderCache; diff --git a/src/rendering/utils/MemoryCalculator.cpp b/src/rendering/utils/MemoryCalculator.cpp index 6d7ae838f3..e2784a05ea 100644 --- a/src/rendering/utils/MemoryCalculator.cpp +++ b/src/rendering/utils/MemoryCalculator.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "MemoryCalculator.h" +#include "base/utils/Log.h" #include "rendering/caches/LayerCache.h" namespace pag { diff --git a/test/framework/utils/LzmaUtil.h b/test/framework/utils/LzmaUtil.h index 064f6aaa6c..04ac701e3b 100644 --- a/test/framework/utils/LzmaUtil.h +++ b/test/framework/utils/LzmaUtil.h @@ -18,6 +18,7 @@ #pragma once +#include #include "core/Data.h" namespace pag { diff --git a/tgfx/include/core/Bitmap.h b/tgfx/include/core/Bitmap.h index 7418971a0b..e92e33ce57 100644 --- a/tgfx/include/core/Bitmap.h +++ b/tgfx/include/core/Bitmap.h @@ -18,9 +18,9 @@ #pragma once -#include "EncodedFormat.h" -#include "ImageInfo.h" #include "core/Data.h" +#include "core/EncodedFormat.h" +#include "core/ImageInfo.h" #include "core/PixelBuffer.h" namespace pag { diff --git a/tgfx/include/core/Blend.h b/tgfx/include/core/Blend.h index c77e8db434..2cc9e83dfb 100644 --- a/tgfx/include/core/Blend.h +++ b/tgfx/include/core/Blend.h @@ -18,8 +18,6 @@ #pragma once -#include "pag/types.h" - namespace pag { /** * Defines constant values for visual blend mode effects. diff --git a/tgfx/include/core/Data.h b/tgfx/include/core/Data.h index 017b910667..c28702b61c 100644 --- a/tgfx/include/core/Data.h +++ b/tgfx/include/core/Data.h @@ -18,7 +18,8 @@ #pragma once -#include "pag/types.h" +#include +#include namespace pag { /** diff --git a/tgfx/include/core/Font.h b/tgfx/include/core/Font.h index 99bf3b0857..f2772cef78 100644 --- a/tgfx/include/core/Font.h +++ b/tgfx/include/core/Font.h @@ -18,7 +18,7 @@ #pragma once -#include "Typeface.h" +#include "core/Typeface.h" namespace pag { /** diff --git a/tgfx/include/core/Image.h b/tgfx/include/core/Image.h index 8188023597..56e1256363 100644 --- a/tgfx/include/core/Image.h +++ b/tgfx/include/core/Image.h @@ -18,11 +18,10 @@ #pragma once -#include "EncodedFormat.h" -#include "ImageInfo.h" -#include "Orientation.h" #include "core/Data.h" -#include "pag/types.h" +#include "core/EncodedFormat.h" +#include "core/ImageInfo.h" +#include "core/Orientation.h" namespace pag { diff --git a/tgfx/include/core/ImageInfo.h b/tgfx/include/core/ImageInfo.h index 919d6b2284..8454490404 100644 --- a/tgfx/include/core/ImageInfo.h +++ b/tgfx/include/core/ImageInfo.h @@ -18,7 +18,6 @@ #pragma once -#include "base/utils/Log.h" #include "pag/types.h" namespace pag { diff --git a/tgfx/include/core/Mask.h b/tgfx/include/core/Mask.h index 760e0a55b7..1f2dddc0db 100644 --- a/tgfx/include/core/Mask.h +++ b/tgfx/include/core/Mask.h @@ -18,10 +18,10 @@ #pragma once -#include "Font.h" -#include "Path.h" -#include "TextBlob.h" +#include "core/Font.h" +#include "core/Path.h" #include "core/Stroke.h" +#include "core/TextBlob.h" #include "gpu/TextureBuffer.h" namespace pag { diff --git a/tgfx/include/core/Path.h b/tgfx/include/core/Path.h index 5544cae46c..76371f1fac 100644 --- a/tgfx/include/core/Path.h +++ b/tgfx/include/core/Path.h @@ -18,8 +18,7 @@ #pragma once -#include "PathTypes.h" -#include "base/utils/Log.h" +#include "core/PathTypes.h" #include "pag/types.h" namespace pag { diff --git a/tgfx/include/core/PathEffect.h b/tgfx/include/core/PathEffect.h index fec518051f..71f8f29ca8 100644 --- a/tgfx/include/core/PathEffect.h +++ b/tgfx/include/core/PathEffect.h @@ -18,7 +18,7 @@ #pragma once -#include "Path.h" +#include "core/Path.h" #include "core/Stroke.h" namespace pag { diff --git a/tgfx/include/core/PathMeasure.h b/tgfx/include/core/PathMeasure.h index 5384c639bc..bf554d98f9 100644 --- a/tgfx/include/core/PathMeasure.h +++ b/tgfx/include/core/PathMeasure.h @@ -18,7 +18,7 @@ #pragma once -#include "Path.h" +#include "core/Path.h" namespace pag { /** diff --git a/tgfx/include/core/PixelBuffer.h b/tgfx/include/core/PixelBuffer.h index 09b7239cd4..e3798be0ad 100644 --- a/tgfx/include/core/PixelBuffer.h +++ b/tgfx/include/core/PixelBuffer.h @@ -18,7 +18,7 @@ #pragma once -#include "ImageInfo.h" +#include "core/ImageInfo.h" #include "gpu/TextureBuffer.h" namespace pag { diff --git a/tgfx/include/core/Stream.h b/tgfx/include/core/Stream.h index 7a449b12d8..4ab72bb1e8 100644 --- a/tgfx/include/core/Stream.h +++ b/tgfx/include/core/Stream.h @@ -18,7 +18,7 @@ #pragma once -#include "pag/types.h" +#include namespace pag { /** diff --git a/tgfx/include/core/TextBlob.h b/tgfx/include/core/TextBlob.h index 97a6f7789a..de6eb2c357 100644 --- a/tgfx/include/core/TextBlob.h +++ b/tgfx/include/core/TextBlob.h @@ -18,8 +18,8 @@ #pragma once -#include "Font.h" -#include "Path.h" +#include "core/Font.h" +#include "core/Path.h" #include "core/Stroke.h" namespace pag { diff --git a/tgfx/include/core/Typeface.h b/tgfx/include/core/Typeface.h index 5cb2c8ee80..36efd4aa13 100644 --- a/tgfx/include/core/Typeface.h +++ b/tgfx/include/core/Typeface.h @@ -18,8 +18,8 @@ #pragma once -#include "FontMetrics.h" -#include "Path.h" +#include "core/FontMetrics.h" +#include "core/Path.h" #include "gpu/TextureBuffer.h" namespace pag { diff --git a/tgfx/include/gpu/Context.h b/tgfx/include/gpu/Context.h index c67798c060..cf1d658ae9 100644 --- a/tgfx/include/gpu/Context.h +++ b/tgfx/include/gpu/Context.h @@ -18,49 +18,51 @@ #pragma once -#include -#include -#include "base/utils/BytesKey.h" -#include "base/utils/UniqueID.h" #include "core/Color4f.h" -#include "gpu/Caps.h" +#include "core/utils/BytesKey.h" #include "gpu/Device.h" #include "pag/gpu.h" namespace pag { +class ProgramCache; -class Resource; - -class Texture; - -class Program; +class GradientCache; -class ProgramCreator; +class ResourceCache; -class GradientCache; +class Caps; class Context { public: virtual ~Context(); /** - * Returns the unique ID of the associated device. + * Returns the associated device. */ - Device* getDevice() const; + Device* device() const { + return _device; + } /** - * Returns a program cache of specified ProgramMaker. If there is no associated cache available, - * a new program will be created by programMaker. Returns null if the programMaker fails to make a - * new program. + * Returns the associated cache that manages the lifetime of all gradients. */ - Program* getProgram(const ProgramCreator* programMaker); + GradientCache* gradientCache() const { + return _gradientCache; + } - const Texture* getGradient(const Color4f* colors, const float* positions, int count); + /** + * Returns the associated cache that manages the lifetime of all Program instances. + */ + ProgramCache* programCache() const { + return _programCache; + } /** - * Returns a reusable resource in the cache. + * Returns the associated cache that manages the lifetime of all Resource instances. */ - std::shared_ptr getRecycledResource(const BytesKey& recycleKey); + ResourceCache* resourceCache() const { + return _resourceCache; + } /** * Purges GPU resources that haven't been used in the past 'usNotUsed' microseconds. @@ -81,24 +83,11 @@ class Context { explicit Context(Device* device); private: - Device* device = nullptr; - bool purgingResource = false; - std::list programLRU = {}; - std::unordered_map programMap = {}; - GradientCache* gradientCache = nullptr; - std::vector nonpurgeableResources = {}; - std::vector> strongReferences = {}; - std::unordered_map, BytesHasher> recycledResources = {}; - std::mutex removeLocker = {}; - std::vector pendingRemovedResources = {}; - - static void AddToList(std::vector& list, Resource* resource); - static void RemoveFromList(std::vector& list, Resource* resource); - static void NotifyReferenceReachedZero(Resource* resource); - - std::shared_ptr wrapResource(Resource* resource); - void removeResource(Resource* resource); - void removeOldestProgram(bool releaseGPU = true); + Device* _device = nullptr; + GradientCache* _gradientCache = nullptr; + ProgramCache* _programCache = nullptr; + ResourceCache* _resourceCache = nullptr; + void releaseAll(bool releaseGPU); void onLocked(); void onUnlocked(); @@ -106,8 +95,6 @@ class Context { friend class Device; friend class Resource; - - friend class PurgeGuard; }; } // namespace pag diff --git a/tgfx/include/gpu/Device.h b/tgfx/include/gpu/Device.h index 3e4603811d..d14627311f 100644 --- a/tgfx/include/gpu/Device.h +++ b/tgfx/include/gpu/Device.h @@ -18,7 +18,6 @@ #pragma once -#include "base/utils/Log.h" #include "pag/types.h" namespace pag { @@ -65,6 +64,6 @@ class Device { uint32_t _uniqueID = 0; bool contextLocked = false; - friend class Context; + friend class ResourceCache; }; } // namespace pag diff --git a/tgfx/include/gpu/Resource.h b/tgfx/include/gpu/Resource.h index 7d82dffb2a..4bf801924c 100644 --- a/tgfx/include/gpu/Resource.h +++ b/tgfx/include/gpu/Resource.h @@ -18,8 +18,7 @@ #pragma once -#include "Context.h" -#include "base/utils/BytesKey.h" +#include "gpu/ResourceCache.h" namespace pag { /** @@ -35,7 +34,7 @@ class Resource { static std::shared_ptr Wrap(Context* context, T* resource) { resource->context = context; static_cast(resource)->computeRecycleKey(&resource->recycleKey); - return std::static_pointer_cast(context->wrapResource(resource)); + return std::static_pointer_cast(context->resourceCache()->wrapResource(resource)); } virtual ~Resource() = default; @@ -60,6 +59,6 @@ class Resource { size_t cacheArrayIndex = 0; int64_t lastUsedTime = 0; - friend class Context; + friend class ResourceCache; }; } // namespace pag diff --git a/tgfx/include/gpu/Texture.h b/tgfx/include/gpu/Texture.h index 75e1bd27c5..22d10d5632 100644 --- a/tgfx/include/gpu/Texture.h +++ b/tgfx/include/gpu/Texture.h @@ -20,9 +20,10 @@ #include #include "gpu/Resource.h" -#include "gpu/TextureSampler.h" namespace pag { +class TextureSampler; + /** * Texture describes a two dimensional array of pixels in the GPU backend for drawing. */ diff --git a/tgfx/src/gpu/opengl/GLDevice.h b/tgfx/include/gpu/opengl/GLDevice.h similarity index 97% rename from tgfx/src/gpu/opengl/GLDevice.h rename to tgfx/include/gpu/opengl/GLDevice.h index 2a7a25dde0..7f53f3ee59 100644 --- a/tgfx/src/gpu/opengl/GLDevice.h +++ b/tgfx/include/gpu/opengl/GLDevice.h @@ -21,6 +21,9 @@ #include "gpu/Device.h" namespace pag { +/** + * The OpenGL interface for drawing graphics. + */ class GLDevice : public Device { public: /** diff --git a/tgfx/include/gpu/opengl/webgl/WebGLDevice.h b/tgfx/include/gpu/opengl/webgl/WebGLDevice.h index e6c731dc8a..7ff242271c 100644 --- a/tgfx/include/gpu/opengl/webgl/WebGLDevice.h +++ b/tgfx/include/gpu/opengl/webgl/WebGLDevice.h @@ -19,7 +19,6 @@ #pragma once #include - #include "gpu/opengl/GLDevice.h" namespace pag { diff --git a/src/base/utils/BytesKey.cpp b/tgfx/src/core/utils/BytesKey.cpp similarity index 98% rename from src/base/utils/BytesKey.cpp rename to tgfx/src/core/utils/BytesKey.cpp index 4867f2f682..30de3c1507 100644 --- a/src/base/utils/BytesKey.cpp +++ b/tgfx/src/core/utils/BytesKey.cpp @@ -16,7 +16,7 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////// -#include "BytesKey.h" +#include "core/utils/BytesKey.h" #include namespace pag { diff --git a/src/base/utils/BytesKey.h b/tgfx/src/core/utils/BytesKey.h similarity index 100% rename from src/base/utils/BytesKey.h rename to tgfx/src/core/utils/BytesKey.h diff --git a/tgfx/src/core/vectors/coregraphics/CGScalerContext.cpp b/tgfx/src/core/vectors/coregraphics/CGScalerContext.cpp index b4ede11dce..5ca38a350e 100644 --- a/tgfx/src/core/vectors/coregraphics/CGScalerContext.cpp +++ b/tgfx/src/core/vectors/coregraphics/CGScalerContext.cpp @@ -18,6 +18,7 @@ #include "core/vectors/coregraphics/CGScalerContext.h" #include "base/utils/Interpolate.h" +#include "base/utils/Log.h" #include "base/utils/MathExtra.h" #include "core/PathEffect.h" #include "platform/apple/BitmapContextUtil.h" diff --git a/tgfx/src/core/vectors/freetype/FTScalerContext.cpp b/tgfx/src/core/vectors/freetype/FTScalerContext.cpp index b6218a56be..c4a4759465 100644 --- a/tgfx/src/core/vectors/freetype/FTScalerContext.cpp +++ b/tgfx/src/core/vectors/freetype/FTScalerContext.cpp @@ -24,6 +24,7 @@ #include FT_SIZES_H #include FT_TRUETYPE_TABLES_H #include "FTUtil.h" +#include "base/utils/Log.h" #include "base/utils/MathExtra.h" #include "core/Bitmap.h" #include "skcms.h" diff --git a/tgfx/src/gpu/AlphaFragmentProcessor.cpp b/tgfx/src/gpu/AlphaFragmentProcessor.cpp index cc2370dff2..049bd014b2 100644 --- a/tgfx/src/gpu/AlphaFragmentProcessor.cpp +++ b/tgfx/src/gpu/AlphaFragmentProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "AlphaFragmentProcessor.h" +#include "base/utils/UniqueID.h" #include "opengl/GLAlphaFragmentProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/ConstColorProcessor.cpp b/tgfx/src/gpu/ConstColorProcessor.cpp index 95c5b2f7c0..7380a6df1b 100644 --- a/tgfx/src/gpu/ConstColorProcessor.cpp +++ b/tgfx/src/gpu/ConstColorProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "ConstColorProcessor.h" +#include "base/utils/UniqueID.h" #include "opengl/GLConstColorProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/Context.cpp b/tgfx/src/gpu/Context.cpp index ded5ce4325..c3fffa78aa 100644 --- a/tgfx/src/gpu/Context.cpp +++ b/tgfx/src/gpu/Context.cpp @@ -17,227 +17,46 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/Context.h" -#include "GradientCache.h" -#include "Program.h" #include "base/utils/GetTimer.h" -#include "gpu/Resource.h" +#include "base/utils/Log.h" +#include "gpu/GradientCache.h" +#include "gpu/Program.h" +#include "gpu/ProgramCache.h" +#include "gpu/ResourceCache.h" namespace pag { -#define MAX_PROGRAM_COUNT 128 -static thread_local Context* threadCurrentContext = nullptr; - -class PurgeGuard { - public: - explicit PurgeGuard(Context* context) : context(context) { - context->purgingResource = true; - } - - ~PurgeGuard() { - context->purgingResource = false; - } - - private: - Context* context = nullptr; -}; - -Context::Context(Device* device) : device(device) { - gradientCache = new GradientCache(this); +Context::Context(Device* device) : _device(device) { + _gradientCache = new GradientCache(this); + _programCache = new ProgramCache(this); + _resourceCache = new ResourceCache(this); } Context::~Context() { // The Device owner must call releaseAll() before deleting this Context, otherwise, GPU resources // may leak. - DEBUG_ASSERT(nonpurgeableResources.empty()); - DEBUG_ASSERT(pendingRemovedResources.empty()); - DEBUG_ASSERT(recycledResources.empty()); - DEBUG_ASSERT(programMap.empty()); - DEBUG_ASSERT(gradientCache->empty()) - delete gradientCache; -} - -Device* Context::getDevice() const { - return device; + DEBUG_ASSERT(_resourceCache->empty()); + DEBUG_ASSERT(_programCache->empty()); + DEBUG_ASSERT(_gradientCache->empty()) + delete _gradientCache; + delete _programCache; + delete _resourceCache; } void Context::onLocked() { - threadCurrentContext = this; - // Triggers NotifyReferenceReachedZero() if a Resource has no other reference. - strongReferences.clear(); + _resourceCache->attachToCurrentThread(); } void Context::onUnlocked() { - for (auto& resource : nonpurgeableResources) { - // Adds a strong reference to the external Resource to make sure it never triggers - // NotifyReferenceReachedZero() while associated device is not locked. - auto strongReference = resource->weakThis.lock(); - if (strongReference) { - strongReferences.push_back(strongReference); - } - } - // strongReferences 保护已经开启,这时候不会再有任何外部的 Resource 会触发 - // NotifyReferenceReachedZero()。 - std::vector removedResources = {}; - std::swap(removedResources, pendingRemovedResources); - for (auto& resource : removedResources) { - removeResource(resource); - } - DEBUG_ASSERT(pendingRemovedResources.empty()); - threadCurrentContext = nullptr; + _resourceCache->detachFromCurrentThread(); } void Context::purgeResourcesNotUsedIn(int64_t usNotUsed) { - PurgeGuard guard(this); - auto currentTime = GetTimer(); - std::unordered_map, BytesHasher> recycledMap = {}; - for (auto& item : recycledResources) { - std::vector needToRecycle = {}; - for (auto& resource : item.second) { - if (currentTime - resource->lastUsedTime < usNotUsed) { - needToRecycle.push_back(resource); - } else { - resource->onRelease(this); - delete resource; - } - } - if (!needToRecycle.empty()) { - recycledMap[item.first] = needToRecycle; - } - } - recycledResources = recycledMap; + _resourceCache->purgeNotUsedIn(usNotUsed); } void Context::releaseAll(bool releaseGPU) { - if (gradientCache) { - gradientCache->releaseAll(); - } - PurgeGuard guard(this); - for (auto& resource : nonpurgeableResources) { - if (releaseGPU) { - resource->onRelease(this); - } - // 标记 Resource 已经被释放,等外部指针计数为 0 时可以直接 delete。 - resource->context = nullptr; - } - nonpurgeableResources.clear(); - while (!programLRU.empty()) { - removeOldestProgram(releaseGPU); - } - for (auto& item : recycledResources) { - for (auto& resource : item.second) { - if (releaseGPU) { - resource->onRelease(this); - } - delete resource; - } - } - recycledResources.clear(); -} - -Program* Context::getProgram(const ProgramCreator* programMaker) { - BytesKey uniqueKey = {}; - programMaker->computeUniqueKey(this, &uniqueKey); - auto result = programMap.find(uniqueKey); - if (result != programMap.end()) { - programLRU.remove(result->second); - programLRU.push_front(result->second); - return result->second; - } - // TODO(domrjchen): createProgram() 应该统计到 programCompilingTime 里。 - auto program = programMaker->createProgram(this).release(); - if (program == nullptr) { - return nullptr; - } - program->uniqueKey = uniqueKey; - programLRU.push_front(program); - programMap[uniqueKey] = program; - while (programLRU.size() > MAX_PROGRAM_COUNT) { - removeOldestProgram(); - } - return program; -} - -const Texture* Context::getGradient(const Color4f* colors, const float* positions, int count) { - return gradientCache->getGradient(colors, positions, count); -} - -std::shared_ptr Context::getRecycledResource(const BytesKey& resourceKey) { - auto result = recycledResources.find(resourceKey); - if (result == recycledResources.end()) { - return nullptr; - } - auto& list = result->second; - auto resource = list.back(); - list.pop_back(); - if (list.empty()) { - recycledResources.erase(result); - } - return wrapResource(resource); -} - -void Context::AddToList(std::vector& list, Resource* resource) { - auto index = list.size(); - list.push_back(resource); - resource->cacheArrayIndex = index; -} - -void Context::RemoveFromList(std::vector& list, Resource* resource) { - auto tail = *(list.end() - 1); - auto index = resource->cacheArrayIndex; - list[index] = tail; - tail->cacheArrayIndex = index; - list.pop_back(); -} - -void Context::NotifyReferenceReachedZero(Resource* resource) { - if (resource->context) { - resource->context->removeResource(resource); - } else { - // Resource 上的属性都是在 Context 加锁的情况下读写的,这里如果 context - // 为空,说明已经被释放了,可以直接删除。 - delete resource; - } -} - -std::shared_ptr Context::wrapResource(Resource* resource) { - AddToList(nonpurgeableResources, resource); - auto result = std::shared_ptr(resource, Context::NotifyReferenceReachedZero); - result->weakThis = result; - return result; -} - -void Context::removeResource(Resource* resource) { - if (threadCurrentContext != this) { - // 当 strongReferences 列表清空时,其他线程的 Resource 也有可能会触发 - // NotifyReferenceReachedZero()。 如果触发的线程不是当前 context 被锁定时的线程, - // 先放进一个队列延后处理。 - std::lock_guard autoLock(removeLocker); - pendingRemovedResources.push_back(resource); - return; - } - // 禁止 Resource 嵌套,防止 Context 析构时无法释放子项。 - DEBUG_ASSERT(!purgingResource); - // 只有 context 锁定的情况下才有可能 - // 触发 NotifyReferenceReachedZero() - DEBUG_ASSERT(device->contextLocked); - RemoveFromList(nonpurgeableResources, resource); - if (resource->recycleKey.isValid()) { - resource->lastUsedTime = GetTimer(); - recycledResources[resource->recycleKey].push_back(resource); - } else { - purgingResource = true; - resource->onRelease(this); - purgingResource = false; - delete resource; - } -} - -void Context::removeOldestProgram(bool releaseGPU) { - auto program = programLRU.back(); - programLRU.pop_back(); - programMap.erase(program->uniqueKey); - if (releaseGPU) { - program->onRelease(this); - } - delete program; + _gradientCache->releaseAll(); + _programCache->releaseAll(releaseGPU); + _resourceCache->releaseAll(releaseGPU); } } // namespace pag \ No newline at end of file diff --git a/tgfx/src/gpu/Device.cpp b/tgfx/src/gpu/Device.cpp index a757c5f9b5..9f85a0fa20 100644 --- a/tgfx/src/gpu/Device.cpp +++ b/tgfx/src/gpu/Device.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/Device.h" +#include "base/utils/Log.h" #include "base/utils/UniqueID.h" #include "gpu/Context.h" diff --git a/tgfx/src/gpu/EllipseGeometryProcessor.cpp b/tgfx/src/gpu/EllipseGeometryProcessor.cpp index 0c1c199592..fed6ce8886 100644 --- a/tgfx/src/gpu/EllipseGeometryProcessor.cpp +++ b/tgfx/src/gpu/EllipseGeometryProcessor.cpp @@ -18,6 +18,7 @@ #include "EllipseGeometryProcessor.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLEllipseGeometryProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/EmptyXferProcessor.cpp b/tgfx/src/gpu/EmptyXferProcessor.cpp index 4723e82308..3e252296b8 100644 --- a/tgfx/src/gpu/EmptyXferProcessor.cpp +++ b/tgfx/src/gpu/EmptyXferProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "EmptyXferProcessor.h" +#include "base/utils/UniqueID.h" #include "opengl/GLEmptyXferProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/GradientCache.h b/tgfx/src/gpu/GradientCache.h index b48c269cba..9513f95e1e 100644 --- a/tgfx/src/gpu/GradientCache.h +++ b/tgfx/src/gpu/GradientCache.h @@ -21,9 +21,9 @@ #include #include -#include "base/utils/BytesKey.h" #include "core/Bitmap.h" #include "core/Color4f.h" +#include "core/utils/BytesKey.h" namespace pag { class Context; diff --git a/tgfx/src/gpu/GradientShader.cpp b/tgfx/src/gpu/GradientShader.cpp index 55d8552e06..cd0ff874ba 100644 --- a/tgfx/src/gpu/GradientShader.cpp +++ b/tgfx/src/gpu/GradientShader.cpp @@ -18,6 +18,7 @@ #include "gpu/GradientShader.h" #include "base/utils/MathExtra.h" +#include "gpu/Caps.h" #include "gpu/ColorShader.h" #include "gpu/ConstColorProcessor.h" #include "gpu/GradientCache.h" @@ -106,7 +107,7 @@ static std::unique_ptr MakeColorizer(Context* context, const // Otherwise, fall back to a raster gradient sample by a texture, which can handle // arbitrary gradients (the only downside being sampling resolution). return TextureGradientColorizer::Make( - context->getGradient(colors + offset, positions + offset, count)); + context->gradientCache()->getGradient(colors + offset, positions + offset, count)); } class GradientShaderBase : public ShaderBase { diff --git a/tgfx/src/gpu/Pipeline.cpp b/tgfx/src/gpu/Pipeline.cpp index 4523f5732b..7c9a8ac3a3 100644 --- a/tgfx/src/gpu/Pipeline.cpp +++ b/tgfx/src/gpu/Pipeline.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "Pipeline.h" +#include "gpu/TextureSampler.h" namespace pag { Pipeline::Pipeline(std::vector> fragmentProcessors, diff --git a/tgfx/src/gpu/PorterDuffXferProcessor.cpp b/tgfx/src/gpu/PorterDuffXferProcessor.cpp index dc7c6cee71..409d9c0ba2 100644 --- a/tgfx/src/gpu/PorterDuffXferProcessor.cpp +++ b/tgfx/src/gpu/PorterDuffXferProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "PorterDuffXferProcessor.h" +#include "base/utils/UniqueID.h" #include "opengl/GLPorterDuffXferProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/Processor.h b/tgfx/src/gpu/Processor.h index 815dfb1c61..e3ef2c5749 100644 --- a/tgfx/src/gpu/Processor.h +++ b/tgfx/src/gpu/Processor.h @@ -18,7 +18,7 @@ #pragma once -#include "base/utils/BytesKey.h" +#include "core/utils/BytesKey.h" #include "gpu/Context.h" namespace pag { diff --git a/tgfx/src/gpu/Program.h b/tgfx/src/gpu/Program.h index 5c969cfb3f..2caea15630 100644 --- a/tgfx/src/gpu/Program.h +++ b/tgfx/src/gpu/Program.h @@ -18,7 +18,7 @@ #pragma once -#include "base/utils/BytesKey.h" +#include "core/utils/BytesKey.h" #include "gpu/Context.h" namespace pag { @@ -40,7 +40,7 @@ class Program { private: BytesKey uniqueKey = {}; - friend class Context; + friend class ProgramCache; }; class ProgramCreator { diff --git a/tgfx/src/gpu/ProgramCache.cpp b/tgfx/src/gpu/ProgramCache.cpp new file mode 100644 index 0000000000..c78e391640 --- /dev/null +++ b/tgfx/src/gpu/ProgramCache.cpp @@ -0,0 +1,69 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. +// +// 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 "ProgramCache.h" + +namespace pag { +#define MAX_PROGRAM_COUNT 128 + +ProgramCache::ProgramCache(Context* context) : context(context) { +} + +bool ProgramCache::empty() const { + return programMap.empty(); +} + +Program* ProgramCache::getProgram(const ProgramCreator* programMaker) { + BytesKey uniqueKey = {}; + programMaker->computeUniqueKey(context, &uniqueKey); + auto result = programMap.find(uniqueKey); + if (result != programMap.end()) { + programLRU.remove(result->second); + programLRU.push_front(result->second); + return result->second; + } + // TODO(domrjchen): createProgram() 应该统计到 programCompilingTime 里。 + auto program = programMaker->createProgram(context).release(); + if (program == nullptr) { + return nullptr; + } + program->uniqueKey = uniqueKey; + programLRU.push_front(program); + programMap[uniqueKey] = program; + while (programLRU.size() > MAX_PROGRAM_COUNT) { + removeOldestProgram(); + } + return program; +} + +void ProgramCache::removeOldestProgram(bool releaseGPU) { + auto program = programLRU.back(); + programLRU.pop_back(); + programMap.erase(program->uniqueKey); + if (releaseGPU) { + program->onRelease(context); + } + delete program; +} + +void ProgramCache::releaseAll(bool releaseGPU) { + while (!programLRU.empty()) { + removeOldestProgram(releaseGPU); + } +} +} // namespace pag diff --git a/tgfx/src/gpu/ProgramCache.h b/tgfx/src/gpu/ProgramCache.h new file mode 100644 index 0000000000..4f16df28ba --- /dev/null +++ b/tgfx/src/gpu/ProgramCache.h @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. +// +// 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 +#include +#include "Program.h" + +namespace pag { +/** + * Manages the lifetime of all Program instances. + */ +class ProgramCache { + public: + explicit ProgramCache(Context* context); + + /** + * Returns true if there is no cache at all. + */ + bool empty() const; + + /** + * Returns a program cache of specified ProgramMaker. If there is no associated cache available, + * a new program will be created by programMaker. Returns null if the programMaker fails to make a + * new program. + */ + Program* getProgram(const ProgramCreator* programMaker); + + private: + Context* context = nullptr; + std::list programLRU = {}; + std::unordered_map programMap = {}; + + void removeOldestProgram(bool releaseGPU = true); + void releaseAll(bool releaseGPU); + + friend class Context; +}; +} // namespace pag diff --git a/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp b/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp index b723e725d6..b0c5fd4250 100644 --- a/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp +++ b/tgfx/src/gpu/QuadPerEdgeAAGeometryProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "QuadPerEdgeAAGeometryProcessor.h" +#include "base/utils/UniqueID.h" #include "gpu/YUVTexture.h" #include "gpu/opengl/GLQuadPerEdgeAAGeometryProcessor.h" diff --git a/tgfx/src/gpu/ResourceCache.cpp b/tgfx/src/gpu/ResourceCache.cpp new file mode 100644 index 0000000000..c1a16105cd --- /dev/null +++ b/tgfx/src/gpu/ResourceCache.cpp @@ -0,0 +1,190 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. +// +// 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 "ResourceCache.h" +#include +#include +#include "base/utils/GetTimer.h" +#include "base/utils/Log.h" +#include "core/utils/BytesKey.h" +#include "gpu/Resource.h" + +namespace pag { +static thread_local std::unordered_set currentThreadCaches = {}; + +class PurgeGuard { + public: + explicit PurgeGuard(ResourceCache* cache) : cache(cache) { + cache->purgingResource = true; + } + + ~PurgeGuard() { + cache->purgingResource = false; + } + + private: + ResourceCache* cache = nullptr; +}; + +ResourceCache::ResourceCache(Context* context) : context(context) { +} + +bool ResourceCache::empty() const { + return nonpurgeableResources.empty() && pendingRemovedResources.empty() && + recycledResources.empty(); +} + +void ResourceCache::attachToCurrentThread() { + currentThreadCaches.insert(this); + // Triggers NotifyReferenceReachedZero() if a Resource has no other reference. + strongReferences.clear(); +} + +void ResourceCache::detachFromCurrentThread() { + for (auto& resource : nonpurgeableResources) { + // Adds a strong reference to the external Resource to make sure it never triggers + // NotifyReferenceReachedZero() while associated device is not locked. + auto strongReference = resource->weakThis.lock(); + if (strongReference) { + strongReferences.push_back(strongReference); + } + } + // strongReferences 保护已经开启,这时候不会再有任何外部的 Resource 会触发 + // NotifyReferenceReachedZero()。 + std::vector removedResources = {}; + std::swap(removedResources, pendingRemovedResources); + for (auto& resource : removedResources) { + removeResource(resource); + } + DEBUG_ASSERT(pendingRemovedResources.empty()); + currentThreadCaches.erase(this); +} + +void ResourceCache::releaseAll(bool releaseGPU) { + PurgeGuard guard(this); + for (auto& resource : nonpurgeableResources) { + if (releaseGPU) { + resource->onRelease(context); + } + // 标记 Resource 已经被释放,等外部指针计数为 0 时可以直接 delete。 + resource->context = nullptr; + } + nonpurgeableResources.clear(); + for (auto& item : recycledResources) { + for (auto& resource : item.second) { + if (releaseGPU) { + resource->onRelease(context); + } + delete resource; + } + } + recycledResources.clear(); +} + +void ResourceCache::purgeNotUsedIn(int64_t usNotUsed) { + PurgeGuard guard(this); + auto currentTime = GetTimer(); + std::unordered_map, BytesHasher> recycledMap = {}; + for (auto& item : recycledResources) { + std::vector needToRecycle = {}; + for (auto& resource : item.second) { + if (currentTime - resource->lastUsedTime < usNotUsed) { + needToRecycle.push_back(resource); + } else { + resource->onRelease(context); + delete resource; + } + } + if (!needToRecycle.empty()) { + recycledMap[item.first] = needToRecycle; + } + } + recycledResources = recycledMap; +} + +std::shared_ptr ResourceCache::getRecycled(const BytesKey& resourceKey) { + auto result = recycledResources.find(resourceKey); + if (result == recycledResources.end()) { + return nullptr; + } + auto& list = result->second; + auto resource = list.back(); + list.pop_back(); + if (list.empty()) { + recycledResources.erase(result); + } + return wrapResource(resource); +} + +void ResourceCache::AddToList(std::vector& list, Resource* resource) { + auto index = list.size(); + list.push_back(resource); + resource->cacheArrayIndex = index; +} + +void ResourceCache::RemoveFromList(std::vector& list, Resource* resource) { + auto tail = *(list.end() - 1); + auto index = resource->cacheArrayIndex; + list[index] = tail; + tail->cacheArrayIndex = index; + list.pop_back(); +} + +void ResourceCache::NotifyReferenceReachedZero(Resource* resource) { + if (resource->context) { + resource->context->resourceCache()->removeResource(resource); + } else { + // Resource 上的属性都是在 Context 加锁的情况下读写的,这里如果 context + // 为空,说明已经被释放了,可以直接删除。 + delete resource; + } +} + +std::shared_ptr ResourceCache::wrapResource(Resource* resource) { + AddToList(nonpurgeableResources, resource); + auto result = std::shared_ptr(resource, ResourceCache::NotifyReferenceReachedZero); + result->weakThis = result; + return result; +} + +void ResourceCache::removeResource(Resource* resource) { + if (currentThreadCaches.count(this) == 0) { + // 当 strongReferences 列表清空时,其他线程的 Resource 也有可能会触发 + // NotifyReferenceReachedZero()。 如果触发的线程不是当前 context 被锁定时的线程, + // 先放进一个队列延后处理。 + std::lock_guard autoLock(removeLocker); + pendingRemovedResources.push_back(resource); + return; + } + // 禁止 Resource 嵌套,防止 Context 析构时无法释放子项。 + DEBUG_ASSERT(!purgingResource); + // 只有 context 锁定的情况下才有可能 + // 触发 NotifyReferenceReachedZero() + DEBUG_ASSERT(context->device()->contextLocked); + RemoveFromList(nonpurgeableResources, resource); + if (resource->recycleKey.isValid()) { + resource->lastUsedTime = GetTimer(); + recycledResources[resource->recycleKey].push_back(resource); + } else { + purgingResource = true; + resource->onRelease(context); + purgingResource = false; + delete resource; + } +} +} // namespace pag diff --git a/tgfx/src/gpu/ResourceCache.h b/tgfx/src/gpu/ResourceCache.h new file mode 100644 index 0000000000..88e9eba84a --- /dev/null +++ b/tgfx/src/gpu/ResourceCache.h @@ -0,0 +1,72 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved. +// +// 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 +#include "gpu/Context.h" + +namespace pag { +class Resource; + +/** + * Manages the lifetime of all Resource instances. + */ +class ResourceCache { + public: + explicit ResourceCache(Context* context); + + /** + * Returns true if there is no cache at all. + */ + bool empty() const; + + /** + * Returns a reusable resource in the cache. + */ + std::shared_ptr getRecycled(const BytesKey& recycleKey); + + /** + * Purges GPU resources that haven't been used in the past 'usNotUsed' microseconds. + */ + void purgeNotUsedIn(int64_t usNotUsed); + + private: + Context* context = nullptr; + bool purgingResource = false; + std::vector nonpurgeableResources = {}; + std::vector> strongReferences = {}; + std::unordered_map, BytesHasher> recycledResources = {}; + std::mutex removeLocker = {}; + std::vector pendingRemovedResources = {}; + + static void AddToList(std::vector& list, Resource* resource); + static void RemoveFromList(std::vector& list, Resource* resource); + static void NotifyReferenceReachedZero(Resource* resource); + + void attachToCurrentThread(); + void detachFromCurrentThread(); + void releaseAll(bool releaseGPU); + std::shared_ptr wrapResource(Resource* resource); + void removeResource(Resource* resource); + + friend class Resource; + friend class Context; + friend class PurgeGuard; +}; +} // namespace pag diff --git a/tgfx/src/gpu/TextureFragmentProcessor.cpp b/tgfx/src/gpu/TextureFragmentProcessor.cpp index 1cd99e369b..7a61f4ee85 100644 --- a/tgfx/src/gpu/TextureFragmentProcessor.cpp +++ b/tgfx/src/gpu/TextureFragmentProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "TextureFragmentProcessor.h" +#include "base/utils/UniqueID.h" #include "opengl/GLTextureFragmentProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/TextureMaskFragmentProcessor.cpp b/tgfx/src/gpu/TextureMaskFragmentProcessor.cpp index 1225f7710c..163ca3841d 100644 --- a/tgfx/src/gpu/TextureMaskFragmentProcessor.cpp +++ b/tgfx/src/gpu/TextureMaskFragmentProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "TextureMaskFragmentProcessor.h" +#include "base/utils/UniqueID.h" #include "opengl/GLTextureMaskFragmentProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/TextureSampler.h b/tgfx/src/gpu/TextureSampler.h index 7d01db391c..1dacf860a4 100644 --- a/tgfx/src/gpu/TextureSampler.h +++ b/tgfx/src/gpu/TextureSampler.h @@ -18,7 +18,7 @@ #pragma once -#include "base/utils/BytesKey.h" +#include "core/utils/BytesKey.h" #include "gpu/Context.h" #include "gpu/PixelConfig.h" diff --git a/tgfx/src/gpu/Window.cpp b/tgfx/src/gpu/Window.cpp index 87e11aff60..6ab8863a39 100644 --- a/tgfx/src/gpu/Window.cpp +++ b/tgfx/src/gpu/Window.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/Window.h" +#include "base/utils/Log.h" #include "gpu/Device.h" namespace pag { @@ -41,7 +42,7 @@ bool Window::checkContext(Context* context) { if (context == nullptr) { return false; } - if (context->getDevice() != device.get()) { + if (context->device() != device.get()) { LOGE("Window::checkContext() : context is not locked from the same device of this window"); return false; } diff --git a/tgfx/src/gpu/XferProcessor.h b/tgfx/src/gpu/XferProcessor.h index ca7d8b1f93..00a748a20b 100644 --- a/tgfx/src/gpu/XferProcessor.h +++ b/tgfx/src/gpu/XferProcessor.h @@ -21,7 +21,7 @@ #include #include "Processor.h" -#include "base/utils/BytesKey.h" +#include "core/utils/BytesKey.h" namespace pag { class GLXferProcessor; diff --git a/tgfx/src/gpu/YUVTextureFragmentProcessor.cpp b/tgfx/src/gpu/YUVTextureFragmentProcessor.cpp index 9f2107d78e..53c8bf9c21 100644 --- a/tgfx/src/gpu/YUVTextureFragmentProcessor.cpp +++ b/tgfx/src/gpu/YUVTextureFragmentProcessor.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "YUVTextureFragmentProcessor.h" +#include "base/utils/UniqueID.h" #include "opengl/GLYUVTextureFragmentProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp b/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp index 36adcda11c..fb06bc86b0 100644 --- a/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp +++ b/tgfx/src/gpu/gradients/ClampedGradientEffect.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "ClampedGradientEffect.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLClampedGradientEffect.h" namespace pag { diff --git a/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp b/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp index 7d95748233..ad18234796 100644 --- a/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/DualIntervalGradientColorizer.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "DualIntervalGradientColorizer.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLDualIntervalGradientColorizer.h" namespace pag { diff --git a/tgfx/src/gpu/gradients/LinearGradientLayout.cpp b/tgfx/src/gpu/gradients/LinearGradientLayout.cpp index 2e7f342eda..ca8d05948d 100644 --- a/tgfx/src/gpu/gradients/LinearGradientLayout.cpp +++ b/tgfx/src/gpu/gradients/LinearGradientLayout.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "LinearGradientLayout.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLLinearGradientLayout.h" namespace pag { diff --git a/tgfx/src/gpu/gradients/RadialGradientLayout.cpp b/tgfx/src/gpu/gradients/RadialGradientLayout.cpp index 9aa90f38a8..7411ca2c11 100644 --- a/tgfx/src/gpu/gradients/RadialGradientLayout.cpp +++ b/tgfx/src/gpu/gradients/RadialGradientLayout.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "RadialGradientLayout.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLRadialGradientLayout.h" namespace pag { diff --git a/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp b/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp index f1f0675f4f..34147592e4 100644 --- a/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/SingleIntervalGradientColorizer.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "SingleIntervalGradientColorizer.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLSingleIntervalGradientColorizer.h" namespace pag { diff --git a/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp b/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp index f9366907aa..222960c4c4 100644 --- a/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/TextureGradientColorizer.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "TextureGradientColorizer.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLTextureGradientColorizer.h" namespace pag { diff --git a/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp b/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp index b0e226f381..95cdf2d876 100644 --- a/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp +++ b/tgfx/src/gpu/gradients/UnrolledBinaryGradientColorizer.cpp @@ -18,6 +18,7 @@ #include "UnrolledBinaryGradientColorizer.h" #include "base/utils/MathExtra.h" +#include "base/utils/UniqueID.h" #include "gpu/opengl/GLUnrolledBinaryGradientColorizer.h" namespace pag { diff --git a/tgfx/src/gpu/opengl/GLBuffer.cpp b/tgfx/src/gpu/opengl/GLBuffer.cpp index fc3ab02dd6..8164702641 100644 --- a/tgfx/src/gpu/opengl/GLBuffer.cpp +++ b/tgfx/src/gpu/opengl/GLBuffer.cpp @@ -19,6 +19,7 @@ #include "GLBuffer.h" #include "GLContext.h" +#include "base/utils/UniqueID.h" namespace pag { static void ComputeRecycleKey(BytesKey* recycleKey, const void* uniqueKey, size_t length) { @@ -33,7 +34,8 @@ static void ComputeRecycleKey(BytesKey* recycleKey, const void* uniqueKey, size_ std::shared_ptr GLBuffer::Make(Context* context, const uint16_t* buffer, size_t length) { BytesKey recycleKey = {}; ComputeRecycleKey(&recycleKey, buffer, length); - auto glBuffer = std::static_pointer_cast(context->getRecycledResource(recycleKey)); + auto glBuffer = + std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (glBuffer != nullptr) { return glBuffer; } diff --git a/tgfx/src/gpu/opengl/GLContext.cpp b/tgfx/src/gpu/opengl/GLContext.cpp index 1df4eebd68..cf195cae4e 100644 --- a/tgfx/src/gpu/opengl/GLContext.cpp +++ b/tgfx/src/gpu/opengl/GLContext.cpp @@ -16,8 +16,8 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////// -#include "GLContext.h" -#include "GLDevice.h" +#include "gpu/opengl/GLContext.h" +#include "gpu/opengl/GLDevice.h" namespace pag { GLContext::GLContext(Device* device, const GLInterface* glInterface) : Context(device) { diff --git a/tgfx/src/gpu/opengl/GLDevice.cpp b/tgfx/src/gpu/opengl/GLDevice.cpp index 7607cca0a6..674206bc84 100644 --- a/tgfx/src/gpu/opengl/GLDevice.cpp +++ b/tgfx/src/gpu/opengl/GLDevice.cpp @@ -16,8 +16,8 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////// -#include "GLDevice.h" -#include "GLContext.h" +#include "gpu/opengl/GLDevice.h" +#include "gpu/opengl/GLContext.h" #include "gpu/opengl/GLUtil.h" namespace pag { diff --git a/tgfx/src/gpu/opengl/GLDrawer.cpp b/tgfx/src/gpu/opengl/GLDrawer.cpp index 3aaa06fa24..0ab40121b7 100644 --- a/tgfx/src/gpu/opengl/GLDrawer.cpp +++ b/tgfx/src/gpu/opengl/GLDrawer.cpp @@ -17,12 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "GLDrawer.h" - #include "GLBlend.h" #include "GLProgramBuilder.h" #include "GLProgramCreator.h" #include "GLUtil.h" +#include "base/utils/UniqueID.h" #include "gpu/PorterDuffXferProcessor.h" +#include "gpu/ProgramCache.h" namespace pag { struct AttribLayout { @@ -62,7 +63,8 @@ void GLDrawer::computeRecycleKey(BytesKey* recycleKey) const { std::shared_ptr GLDrawer::Make(Context* context) { BytesKey recycleKey = {}; ComputeRecycleKey(&recycleKey); - auto drawer = std::static_pointer_cast(context->getRecycledResource(recycleKey)); + auto drawer = + std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (drawer != nullptr) { return drawer; } @@ -193,7 +195,7 @@ void GLDrawer::draw(DrawArgs args, std::unique_ptr op) const { GLStateGuard stateGuard(args.context); auto geometryProcessor = op->getGeometryProcessor(args); GLProgramCreator creator(geometryProcessor.get(), &pipeline); - auto program = static_cast(args.context->getProgram(&creator)); + auto program = static_cast(args.context->programCache()->getProgram(&creator)); if (program == nullptr) { return; } diff --git a/tgfx/src/gpu/opengl/GLEllipseGeometryProcessor.cpp b/tgfx/src/gpu/opengl/GLEllipseGeometryProcessor.cpp index 7373d86f33..5011e094d1 100644 --- a/tgfx/src/gpu/opengl/GLEllipseGeometryProcessor.cpp +++ b/tgfx/src/gpu/opengl/GLEllipseGeometryProcessor.cpp @@ -17,7 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "GLEllipseGeometryProcessor.h" - +#include "gpu/Caps.h" #include "gpu/EllipseGeometryProcessor.h" namespace pag { diff --git a/tgfx/src/gpu/opengl/GLTexture.cpp b/tgfx/src/gpu/opengl/GLTexture.cpp index 11136e7b6b..4323ba3c5d 100644 --- a/tgfx/src/gpu/opengl/GLTexture.cpp +++ b/tgfx/src/gpu/opengl/GLTexture.cpp @@ -18,6 +18,7 @@ #include "GLTexture.h" #include "GLUtil.h" +#include "base/utils/UniqueID.h" #include "core/Bitmap.h" #include "gpu/Surface.h" @@ -134,7 +135,8 @@ std::shared_ptr Texture::Make(Context* context, int width, int height, GLRGBATexture::ComputeRecycleKey(&recycleKey, width, height); } - auto texture = std::static_pointer_cast(context->getRecycledResource(recycleKey)); + auto texture = + std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); GLTextureInfo glInfo = {}; if (texture) { texture->_origin = origin; diff --git a/tgfx/src/gpu/opengl/GLYUVTexture.cpp b/tgfx/src/gpu/opengl/GLYUVTexture.cpp index 27bac4dd75..15689ca0ee 100644 --- a/tgfx/src/gpu/opengl/GLYUVTexture.cpp +++ b/tgfx/src/gpu/opengl/GLYUVTexture.cpp @@ -18,6 +18,7 @@ #include "GLYUVTexture.h" #include "GLUtil.h" +#include "base/utils/UniqueID.h" namespace pag { #define I420_PLANE_COUNT 3 @@ -148,7 +149,8 @@ std::shared_ptr YUVTexture::MakeI420(Context* context, YUVColorSpace BytesKey recycleKey = {}; GLI420Texture::ComputeRecycleKey(&recycleKey, width, height); - auto texture = std::static_pointer_cast(context->getRecycledResource(recycleKey)); + auto texture = + std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (texture == nullptr) { auto texturePlanes = MakeTexturePlanes(gl, yuvConfig); if (texturePlanes.empty()) { @@ -183,7 +185,8 @@ std::shared_ptr YUVTexture::MakeNV12(Context* context, YUVColorSpace BytesKey recycleKey = {}; GLNV12Texture::ComputeRecycleKey(&recycleKey, width, height); - auto texture = std::static_pointer_cast(context->getRecycledResource(recycleKey)); + auto texture = + std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (texture == nullptr) { auto texturePlanes = MakeTexturePlanes(gl, yuvConfig); if (texturePlanes.empty()) { diff --git a/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm b/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm index 23fe4fc771..2d346d2c7a 100644 --- a/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm +++ b/tgfx/src/gpu/opengl/cgl/CGLHardwareTexture.mm @@ -18,6 +18,7 @@ #include "CGLHardwareTexture.h" #include "gpu/opengl/cgl/CGLDevice.h" +#include "base/utils/UniqueID.h" namespace pag { std::shared_ptr CGLHardwareTexture::MakeFrom(Context* context, @@ -25,11 +26,11 @@ BytesKey recycleKey = {}; ComputeRecycleKey(&recycleKey, pixelBuffer); auto glTexture = - std::static_pointer_cast(context->getRecycledResource(recycleKey)); + std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (glTexture) { return glTexture; } - auto cglDevice = static_cast(context->getDevice()); + auto cglDevice = static_cast(context->device()); if (cglDevice == nullptr) { return nullptr; } @@ -102,7 +103,7 @@ } CFRelease(texture); texture = nil; - auto cglDevice = static_cast(context->getDevice()); + auto cglDevice = static_cast(context->device()); auto textureCache = cglDevice->getTextureCache(); CVOpenGLTextureCacheFlush(textureCache, 0); } diff --git a/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm b/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm index 609cc596da..89b9556ae6 100644 --- a/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm +++ b/tgfx/src/gpu/opengl/eagl/EAGLHardwareTexture.mm @@ -18,6 +18,7 @@ #include "EAGLHardwareTexture.h" #include "gpu/opengl/eagl/EAGLDevice.h" +#include "base/utils/UniqueID.h" namespace pag { static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pixelBuffer, @@ -63,11 +64,11 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix BytesKey recycleKey = {}; ComputeRecycleKey(&recycleKey, pixelBuffer); glTexture = - std::static_pointer_cast(context->getRecycledResource(recycleKey)); + std::static_pointer_cast(context->resourceCache()->getRecycled(recycleKey)); if (glTexture) { return glTexture; } - auto eaglDevice = static_cast(context->getDevice()); + auto eaglDevice = static_cast(context->device()); if (eaglDevice == nullptr) { return nullptr; } @@ -125,7 +126,7 @@ static CVOpenGLESTextureRef GetTextureRef(Context* context, CVPixelBufferRef pix if (texture == nil) { return; } - static_cast(context->getDevice())->releaseTexture(texture); + static_cast(context->device())->releaseTexture(texture); texture = nil; } } diff --git a/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm b/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm index 51cb5fc64f..0994b786fe 100644 --- a/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm +++ b/tgfx/src/gpu/opengl/eagl/EAGLWindow.mm @@ -128,7 +128,7 @@ gl->bindRenderbuffer(GL::RENDERBUFFER, colorBuffer); gl->framebufferRenderbuffer(GL::FRAMEBUFFER, GL::COLOR_ATTACHMENT0, GL::RENDERBUFFER, colorBuffer); - auto eaglContext = static_cast(context->getDevice())->eaglContext(); + auto eaglContext = static_cast(context->device())->eaglContext(); [eaglContext renderbufferStorage:GL::RENDERBUFFER fromDrawable:layer]; auto frameBufferStatus = gl->checkFramebufferStatus(GL::FRAMEBUFFER); gl->bindFramebuffer(GL::FRAMEBUFFER, 0); @@ -148,7 +148,7 @@ auto gl = GLContext::Unwrap(context); if (layer) { gl->bindRenderbuffer(GL::RENDERBUFFER, colorBuffer); - auto eaglContext = static_cast(context->getDevice())->eaglContext(); + auto eaglContext = static_cast(context->device())->eaglContext(); [eaglContext presentRenderbuffer:GL::RENDERBUFFER]; gl->bindRenderbuffer(GL::RENDERBUFFER, 0); } else { diff --git a/tgfx/src/gpu/opengl/egl/EGLDevice.cpp b/tgfx/src/gpu/opengl/egl/EGLDevice.cpp index 90796d3953..c2439402d0 100644 --- a/tgfx/src/gpu/opengl/egl/EGLDevice.cpp +++ b/tgfx/src/gpu/opengl/egl/EGLDevice.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/opengl/egl/EGLDevice.h" +#include "base/utils/Log.h" #include "gpu/opengl/egl/EGLGlobals.h" #include "gpu/opengl/egl/EGLProcGetter.h" diff --git a/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp b/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp index e7fd8a0149..6b3f81d205 100644 --- a/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp +++ b/tgfx/src/gpu/opengl/egl/EGLHardwareTexture.cpp @@ -22,6 +22,7 @@ #include #include #include +#include "base/utils/UniqueID.h" #include "gpu/opengl/egl/EGLDevice.h" #include "platform/android/HardwareBuffer.h" #include "platform/android/HardwareBufferInterface.h" @@ -53,8 +54,8 @@ std::shared_ptr EGLHardwareTexture::MakeFrom(Context* contex } BytesKey recycleKey = {}; ComputeRecycleKey(&recycleKey, hardwareBuffer); - auto glTexture = - std::static_pointer_cast(context->getRecycledResource(recycleKey)); + auto glTexture = std::static_pointer_cast( + context->resourceCache()->getRecycled(recycleKey)); if (glTexture != nullptr) { return glTexture; } @@ -62,7 +63,7 @@ std::shared_ptr EGLHardwareTexture::MakeFrom(Context* contex if (!clientBuffer) { return nullptr; } - auto display = static_cast(context->getDevice())->getDisplay(); + auto display = static_cast(context->device())->getDisplay(); EGLint attributes[] = {EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE}; EGLImageKHR eglImage = eglext::eglCreateImageKHR( display, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, clientBuffer, attributes); @@ -111,7 +112,7 @@ void EGLHardwareTexture::ComputeRecycleKey(BytesKey* recycleKey, void* hardwareB void EGLHardwareTexture::onRelease(Context* context) { auto gl = GLContext::Unwrap(context); gl->deleteTextures(1, &sampler.glInfo.id); - auto display = static_cast(context->getDevice())->getDisplay(); + auto display = static_cast(context->device())->getDisplay(); eglext::eglDestroyImageKHR(display, eglImage); } } // namespace pag diff --git a/tgfx/src/gpu/opengl/qt/QGLDevice.cpp b/tgfx/src/gpu/opengl/qt/QGLDevice.cpp index 95a9bb85b1..9d59960fdd 100644 --- a/tgfx/src/gpu/opengl/qt/QGLDevice.cpp +++ b/tgfx/src/gpu/opengl/qt/QGLDevice.cpp @@ -20,6 +20,7 @@ #include #include #include "QGLProcGetter.h" +#include "base/utils/Log.h" namespace pag { void* GLDevice::CurrentNativeHandle() { diff --git a/tgfx/src/gpu/opengl/webgl/WebGLDevice.cpp b/tgfx/src/gpu/opengl/webgl/WebGLDevice.cpp index aaa688a61f..5fab5fcba3 100644 --- a/tgfx/src/gpu/opengl/webgl/WebGLDevice.cpp +++ b/tgfx/src/gpu/opengl/webgl/WebGLDevice.cpp @@ -18,6 +18,7 @@ #include "gpu/opengl/webgl/WebGLDevice.h" #include "WebGLProcGetter.h" +#include "base/utils/Log.h" namespace pag { diff --git a/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp b/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp index 7fa90018cf..a1537ff498 100644 --- a/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp +++ b/tgfx/src/gpu/opengl/webgl/WebGLWindow.cpp @@ -17,6 +17,7 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "gpu/opengl/webgl/WebGLWindow.h" +#include "base/utils/Log.h" #include "gpu/opengl/GLDefines.h" namespace pag {