diff options
Diffstat (limited to 'gfx/skia/skia/src/image/SkImage_Gpu.h')
-rw-r--r-- | gfx/skia/skia/src/image/SkImage_Gpu.h | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/image/SkImage_Gpu.h b/gfx/skia/skia/src/image/SkImage_Gpu.h new file mode 100644 index 0000000000..71cebb0eb1 --- /dev/null +++ b/gfx/skia/skia/src/image/SkImage_Gpu.h @@ -0,0 +1,179 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkImage_Gpu_DEFINED +#define SkImage_Gpu_DEFINED + +#include "include/core/SkRefCnt.h" +#include "include/core/SkSamplingOptions.h" +#include "include/gpu/GrBackendSurface.h" +#include "include/private/SkSpinlock.h" +#include "include/private/base/SkThreadAnnotations.h" +#include "src/gpu/Swizzle.h" +#include "src/gpu/ganesh/GrSurfaceProxyView.h" +#include "src/image/SkImage_Base.h" +#include "src/image/SkImage_GpuBase.h" + +#include <cstddef> +#include <cstdint> +#include <memory> +#include <tuple> + +class GrDirectContext; +class GrFragmentProcessor; +class GrImageContext; +class GrRecordingContext; +class GrRenderTask; +class GrSurfaceProxy; +class SkColorInfo; +class SkColorSpace; +class SkImage; +class SkMatrix; +enum GrSurfaceOrigin : int; +enum SkColorType : int; +enum SkYUVColorSpace : int; +enum class GrColorType; +enum class GrImageTexGenPolicy : int; +enum class GrSemaphoresSubmitted : bool; +enum class SkTileMode; +struct GrFlushInfo; +struct SkIRect; +struct SkISize; +struct SkImageInfo; +struct SkRect; + +namespace skgpu { +enum class Mipmapped : bool; +} + +class SkImage_Gpu final : public SkImage_GpuBase { +public: + SkImage_Gpu(sk_sp<GrImageContext> context, + uint32_t uniqueID, + GrSurfaceProxyView view, + SkColorInfo info); + + static sk_sp<SkImage> MakeWithVolatileSrc(sk_sp<GrRecordingContext> rContext, + GrSurfaceProxyView volatileSrc, + SkColorInfo colorInfo); + + ~SkImage_Gpu() override; + + // If this is image is a cached SkSurface snapshot then this method is called by the SkSurface + // before a write to check if the surface must make a copy to avoid modifying the image's + // contents. + bool surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const; + + bool onHasMipmaps() const override; + + GrSemaphoresSubmitted onFlush(GrDirectContext*, const GrFlushInfo&) const override; + + GrBackendTexture onGetBackendTexture(bool flushPendingGrContextIO, + GrSurfaceOrigin* origin) const final; + + SkImage_Base::Type type() const override { return SkImage_Base::Type::kGanesh; } + + size_t onTextureSize() const override; + + using SkImage_GpuBase::onMakeColorTypeAndColorSpace; + sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, + sk_sp<SkColorSpace>, + GrDirectContext*) const final; + + sk_sp<SkImage> onReinterpretColorSpace(sk_sp<SkColorSpace>) const final; + + void onAsyncRescaleAndReadPixels(const SkImageInfo&, + SkIRect srcRect, + RescaleGamma, + RescaleMode, + ReadPixelsCallback, + ReadPixelsContext) const override; + + void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace, + sk_sp<SkColorSpace>, + SkIRect srcRect, + SkISize dstSize, + RescaleGamma, + RescaleMode, + ReadPixelsCallback, + ReadPixelsContext) const override; + + void generatingSurfaceIsDeleted() override; + +private: + SkImage_Gpu(sk_sp<GrDirectContext>, + GrSurfaceProxyView volatileSrc, + sk_sp<GrSurfaceProxy> stableCopy, + sk_sp<GrRenderTask> copyTask, + int volatileSrcTargetCount, + SkColorInfo); + + std::tuple<GrSurfaceProxyView, GrColorType> onAsView(GrRecordingContext*, + skgpu::Mipmapped, + GrImageTexGenPolicy) const override; + + std::unique_ptr<GrFragmentProcessor> onAsFragmentProcessor(GrRecordingContext*, + SkSamplingOptions, + const SkTileMode[2], + const SkMatrix&, + const SkRect*, + const SkRect*) const override; + + GrSurfaceProxyView makeView(GrRecordingContext*) const; + + // Thread-safe wrapper around the proxies backing this image. Handles dynamically switching + // from a "volatile" proxy that may be overwritten (by an SkSurface that this image was snapped + // from) to a "stable" proxy that is a copy of the volatile proxy. It allows the image to cancel + // the copy if the stable proxy is never required because the contents of the volatile proxy + // were never mutated by the SkSurface during the image lifetime. + class ProxyChooser { + public: + ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy, + sk_sp<GrSurfaceProxy> volatileProxy, + sk_sp<GrRenderTask> copyTask, + int volatileProxyTargetCount); + + ProxyChooser(sk_sp<GrSurfaceProxy> stableProxy); + + ~ProxyChooser(); + + // Checks if there is a volatile proxy that is safe to use. If so returns it, otherwise + // returns the stable proxy (and drops the volatile one if it exists). + sk_sp<GrSurfaceProxy> chooseProxy(GrRecordingContext* context) SK_EXCLUDES(fLock); + // Call when it is known copy is necessary. + sk_sp<GrSurfaceProxy> switchToStableProxy() SK_EXCLUDES(fLock); + // Call when it is known for sure copy won't be necessary. + sk_sp<GrSurfaceProxy> makeVolatileProxyStable() SK_EXCLUDES(fLock); + + bool surfaceMustCopyOnWrite(GrSurfaceProxy* surfaceProxy) const SK_EXCLUDES(fLock); + + // Queries that should be independent of which proxy is in use. + size_t gpuMemorySize() const SK_EXCLUDES(fLock); + skgpu::Mipmapped mipmapped() const SK_EXCLUDES(fLock); +#ifdef SK_DEBUG + GrBackendFormat backendFormat() SK_EXCLUDES(fLock); +#endif + + private: + mutable SkSpinlock fLock; + sk_sp<GrSurfaceProxy> fStableProxy SK_GUARDED_BY(fLock); + sk_sp<GrSurfaceProxy> fVolatileProxy SK_GUARDED_BY(fLock); + sk_sp<GrRenderTask> fVolatileToStableCopyTask; + // The number of GrRenderTasks targeting the volatile proxy at creation time. If the + // proxy's target count increases it indicates additional writes and we must switch + // to using the stable copy. + const int fVolatileProxyTargetCount = 0; + }; + + mutable ProxyChooser fChooser; + skgpu::Swizzle fSwizzle; + GrSurfaceOrigin fOrigin; + + using INHERITED = SkImage_GpuBase; +}; + +#endif |