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