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&) 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) 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) override; 73 74 void generatingSurfaceIsDeleted() override; 75 76 private: 77 SkImage_Gpu(sk_sp<GrDirectContext>, 78 GrSurfaceProxyView volatileSrc, 79 sk_sp<GrSurfaceProxy> stableCopy, 80 sk_sp<GrRenderTask> copyTask, 81 int volatileSrcTargetCount, 82 SkColorInfo); 83 84 std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*, 85 GrMipmapped, 86 GrImageTexGenPolicy) const override; 87 88 std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(GrRecordingContext*, 89 SkSamplingOptions, 90 const SkTileMode[], 91 const SkMatrix&, 92 const SkRect*, 93 const SkRect*) const override; 94 95 GrSurfaceProxyView makeView(GrRecordingContext*) const; 96 97 // Thread-safe wrapper around the proxies backing this image. Handles dynamically switching 98 // from a "volatile" proxy that may be overwritten (by an SkSurface that this image was snapped 99 // from) to a "stable" proxy that is a copy of the volatile proxy. It allows the image to cancel 100 // the copy if the stable proxy is never required because the contents of the volatile proxy 101 // were never mutated by the SkSurface during the image lifetime. 102 class ProxyChooser { 103 public: 104 ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy, 105 sk_sp<GrSurfaceProxy> volatileProxy, 106 sk_sp<GrRenderTask> copyTask, 107 int volatileProxyTargetCount); 108 109 ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy); 110 111 ~ProxyChooser(); 112 113 // Checks if there is a volatile proxy that is safe to use. If so returns it, otherwise 114 // returns the stable proxy (and drops the volatile one if it exists). 115 sk_sp<GrSurfaceProxy> chooseProxy(GrRecordingContext* context) SK_EXCLUDES(fLock); 116 // Call when it is known copy is necessary. 117 sk_sp<GrSurfaceProxy> switchToStableProxy() SK_EXCLUDES(fLock); 118 // Call when it is known for sure copy won't be necessary. 119 sk_sp<GrSurfaceProxy> makeVolatileProxyStable() SK_EXCLUDES(fLock); 120 121 bool surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const SK_EXCLUDES(fLock); 122 123 // Queries that should be independent of which proxy is in use. 124 size_t gpuMemorySize() const SK_EXCLUDES(fLock); 125 GrMipmapped mipmapped() const SK_EXCLUDES(fLock); 126 #ifdef SK_DEBUG 127 GrBackendFormat backendFormat() SK_EXCLUDES(fLock); 128 #endif 129 130 private: 131 mutable SkSpinlock fLock; 132 sk_sp<GrSurfaceProxy> fStableProxy SK_GUARDED_BY(fLock); 133 sk_sp<GrSurfaceProxy> fVolatileProxy SK_GUARDED_BY(fLock); 134 sk_sp<GrRenderTask> fVolatileToStableCopyTask; 135 // The number of GrRenderTasks targeting the volatile proxy at creation time. If the 136 // proxy's target count increases it indicates additional writes and we must switch 137 // to using the stable copy. 138 const int fVolatileProxyTargetCount = 0; 139 }; 140 141 mutable ProxyChooser fChooser; 142 GrSwizzle fSwizzle; 143 GrSurfaceOrigin fOrigin; 144 145 using INHERITED = SkImage_GpuBase; 146 }; 147 148 #endif 149