1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkImage_Gpu_DEFINED 9 #define SkImage_Gpu_DEFINED 10 11 #include "include/core/SkRefCnt.h" 12 #include "include/core/SkSamplingOptions.h" 13 #include "include/gpu/GrBackendSurface.h" 14 #include "include/private/SkSpinlock.h" 15 #include "include/private/base/SkThreadAnnotations.h" 16 #include "src/gpu/Swizzle.h" 17 #include "src/gpu/ganesh/GrSurfaceProxyView.h" 18 #include "src/image/SkImage_GpuBase.h" 19 20 #include <cstddef> 21 #include <cstdint> 22 #include <memory> 23 #include <tuple> 24 25 class GrDirectContext; 26 class GrFragmentProcessor; 27 class GrImageContext; 28 class GrRecordingContext; 29 class GrRenderTask; 30 class GrSurfaceProxy; 31 class SkColorInfo; 32 class SkColorSpace; 33 class SkImage; 34 class SkMatrix; 35 enum GrSurfaceOrigin : int; 36 enum SkColorType : int; 37 enum SkYUVColorSpace : int; 38 enum class GrColorType; 39 enum class GrImageTexGenPolicy : int; 40 enum class GrSemaphoresSubmitted : bool; 41 enum class SkTileMode; 42 struct GrFlushInfo; 43 struct SkIRect; 44 struct SkISize; 45 struct SkImageInfo; 46 struct SkRect; 47 48 namespace skgpu { 49 enum class Mipmapped : bool; 50 } 51 52 class SkImage_Gpu final : public SkImage_GpuBase { 53 public: 54 SkImage_Gpu(sk_sp<GrImageContext> context, 55 uint32_t uniqueID, 56 GrSurfaceProxyView view, 57 SkColorInfo info); 58 59 static sk_sp<SkImage> MakeWithVolatileSrc(sk_sp<GrRecordingContext> rContext, 60 GrSurfaceProxyView volatileSrc, 61 SkColorInfo colorInfo); 62 63 ~SkImage_Gpu() override; 64 65 // If this is image is a cached SkSurface snapshot then this method is called by the SkSurface 66 // before a write to check if the surface must make a copy to avoid modifying the image's 67 // contents. 68 bool surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const; 69 70 bool onHasMipmaps() const override; 71 72 GrSemaphoresSubmitted onFlush(GrDirectContext*, const GrFlushInfo&) const override; 73 74 GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO, 75 GrSurfaceOrigin* origin) const final; 76 isGaneshBacked()77 bool isGaneshBacked() const override { return true; } 78 79 size_t onTextureSize() const override; 80 81 using SkImage_GpuBase::onMakeColorTypeAndColorSpace; 82 sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, 83 sk_sp<SkColorSpace>, 84 GrDirectContext*) const final; 85 86 sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const final; 87 88 void onAsyncRescaleAndReadPixels(const SkImageInfo&, 89 SkIRect srcRect, 90 RescaleGamma, 91 RescaleMode, 92 ReadPixelsCallback, 93 ReadPixelsContext) const override; 94 95 void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace, 96 sk_sp<SkColorSpace>, 97 SkIRect srcRect, 98 SkISize dstSize, 99 RescaleGamma, 100 RescaleMode, 101 ReadPixelsCallback, 102 ReadPixelsContext) const override; 103 104 void generatingSurfaceIsDeleted() override; 105 106 private: 107 SkImage_Gpu(sk_sp<GrDirectContext>, 108 GrSurfaceProxyView volatileSrc, 109 sk_sp<GrSurfaceProxy> stableCopy, 110 sk_sp<GrRenderTask> copyTask, 111 int volatileSrcTargetCount, 112 SkColorInfo); 113 114 std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*, 115 skgpu::Mipmapped, 116 GrImageTexGenPolicy) const override; 117 118 std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(GrRecordingContext*, 119 SkSamplingOptions, 120 const SkTileMode[2], 121 const SkMatrix&, 122 const SkRect*, 123 const SkRect*) const override; 124 125 GrSurfaceProxyView makeView(GrRecordingContext*) const; 126 127 // Thread-safe wrapper around the proxies backing this image. Handles dynamically switching 128 // from a "volatile" proxy that may be overwritten (by an SkSurface that this image was snapped 129 // from) to a "stable" proxy that is a copy of the volatile proxy. It allows the image to cancel 130 // the copy if the stable proxy is never required because the contents of the volatile proxy 131 // were never mutated by the SkSurface during the image lifetime. 132 class ProxyChooser { 133 public: 134 ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy, 135 sk_sp<GrSurfaceProxy> volatileProxy, 136 sk_sp<GrRenderTask> copyTask, 137 int volatileProxyTargetCount); 138 139 ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy); 140 141 ~ProxyChooser(); 142 143 // Checks if there is a volatile proxy that is safe to use. If so returns it, otherwise 144 // returns the stable proxy (and drops the volatile one if it exists). 145 sk_sp<GrSurfaceProxy> chooseProxy(GrRecordingContext* context) SK_EXCLUDES(fLock); 146 // Call when it is known copy is necessary. 147 sk_sp<GrSurfaceProxy> switchToStableProxy() SK_EXCLUDES(fLock); 148 // Call when it is known for sure copy won't be necessary. 149 sk_sp<GrSurfaceProxy> makeVolatileProxyStable() SK_EXCLUDES(fLock); 150 151 bool surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const SK_EXCLUDES(fLock); 152 153 // Queries that should be independent of which proxy is in use. 154 size_t gpuMemorySize() const SK_EXCLUDES(fLock); 155 skgpu::Mipmapped mipmapped() const SK_EXCLUDES(fLock); 156 #ifdef SK_DEBUG 157 GrBackendFormat backendFormat() SK_EXCLUDES(fLock); 158 #endif 159 160 private: 161 mutable SkSpinlock fLock; 162 sk_sp<GrSurfaceProxy> fStableProxy SK_GUARDED_BY(fLock); 163 sk_sp<GrSurfaceProxy> fVolatileProxy SK_GUARDED_BY(fLock); 164 sk_sp<GrRenderTask> fVolatileToStableCopyTask; 165 // The number of GrRenderTasks targeting the volatile proxy at creation time. If the 166 // proxy's target count increases it indicates additional writes and we must switch 167 // to using the stable copy. 168 const int fVolatileProxyTargetCount = 0; 169 }; 170 171 mutable ProxyChooser fChooser; 172 skgpu::Swizzle fSwizzle; 173 GrSurfaceOrigin fOrigin; 174 175 using INHERITED = SkImage_GpuBase; 176 }; 177 178 #endif 179