1 /* 2 * Copyright 2023 Google LLC 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 skgpu_graphite_Image_Base_Graphite_DEFINED 9 #define skgpu_graphite_Image_Base_Graphite_DEFINED 10 11 #include "include/gpu/GpuTypes.h" 12 #include "include/private/base/SkTArray.h" 13 #include "src/base/SkSpinlock.h" 14 #include "src/image/SkImage_Base.h" 15 16 #include <string_view> 17 18 enum class SkBackingFit; 19 20 namespace skgpu::graphite { 21 22 class Context; 23 class Device; 24 class DrawContext; 25 class Image; 26 class Recorder; 27 class TextureProxy; 28 29 class Image_Base : public SkImage_Base { 30 public: 31 ~Image_Base() override; 32 33 // Must be called at the time of recording an action that reads from the image, be it a draw 34 // or a copy operation. `drawContext` can be null if the "use" is scoped by a draw. 35 void notifyInUse(Recorder*, DrawContext* drawContext) const; 36 37 // Returns true if this image is linked to a device that may render their shared texture(s). 38 bool isDynamic() const; 39 40 // Always copy this image, even if 'subset' and mipmapping match this image exactly. 41 // The base implementation performs all copies as draws. 42 virtual sk_sp<Image> copyImage(Recorder*, 43 const SkIRect& subset, 44 Budgeted, 45 Mipmapped, 46 SkBackingFit, 47 std::string_view label) const; 48 49 // From SkImage.h 50 // TODO(egdaniel) This feels wrong. Re-think how this method is used and works. isValid(GrRecordingContext *)51 bool isValid(GrRecordingContext*) const override { return true; } 52 53 // From SkImage_Base.h 54 sk_sp<SkImage> onMakeSubset(Recorder*, const SkIRect&, RequiredProperties) const override; 55 sk_sp<SkImage> makeColorTypeAndColorSpace(Recorder*, 56 SkColorType targetCT, 57 sk_sp<SkColorSpace> targetCS, 58 RequiredProperties) const override; 59 60 // No-ops for Ganesh APIs onReadPixels(GrDirectContext *,const SkImageInfo & dstInfo,void * dstPixels,size_t dstRowBytes,int srcX,int srcY,CachingHint)61 bool onReadPixels(GrDirectContext*, 62 const SkImageInfo& dstInfo, 63 void* dstPixels, 64 size_t dstRowBytes, 65 int srcX, 66 int srcY, 67 CachingHint) const override { return false; } 68 69 bool getROPixels(GrDirectContext*, 70 SkBitmap*, 71 CachingHint = kAllow_CachingHint) const override { return false; } 72 73 sk_sp<SkImage> onMakeSubset(GrDirectContext*, const SkIRect&) const override; 74 75 sk_sp<SkSurface> onMakeSurface(Recorder*, const SkImageInfo&) const override; 76 77 sk_sp<SkImage> onMakeColorTypeAndColorSpace(SkColorType, 78 sk_sp<SkColorSpace>, 79 GrDirectContext*) const override; 80 81 void onAsyncRescaleAndReadPixels(const SkImageInfo&, 82 SkIRect srcRect, 83 RescaleGamma, 84 RescaleMode, 85 ReadPixelsCallback, 86 ReadPixelsContext) const override; 87 88 void onAsyncRescaleAndReadPixelsYUV420(SkYUVColorSpace, 89 bool readAlpha, 90 sk_sp<SkColorSpace>, 91 SkIRect srcRect, 92 SkISize dstSize, 93 RescaleGamma, 94 RescaleMode, 95 ReadPixelsCallback, 96 ReadPixelsContext) const override; 97 98 protected: 99 Image_Base(const SkImageInfo& info, uint32_t uniqueID); 100 101 // If the passed-in image is linked with Devices that modify its texture, copy the links to 102 // this Image. This is used when a new Image is created that shares the same texture proxy as 103 // a dynamic image. This can only be called before the Image has been returned from a factory. 104 void linkDevices(const Image_Base*); 105 // Link this image to the Device that can write to their shared texture proxy, so that when the 106 // image is sampled in a draw, any pending work from the Device is automatically flushed. This 107 // can only be called before the Image has been returned from a factory function. 108 void linkDevice(sk_sp<Device>); 109 110 private: 111 // Devices are flushed in notifyImageInUse(). If a linked device is uniquely held by the image 112 // or if it's marked as immutable, it will be unlinked (allowing it to be destroyed eventually). 113 // If all linked devices are removed, this array will become empty. Other than initialization, 114 // this array cannot transition from an empty state to having linked devices, so while it's 115 // empty no locking is required. 116 mutable skia_private::STArray<1, sk_sp<Device>> fLinkedDevices SK_GUARDED_BY(fDeviceLinkLock); 117 mutable SkSpinlock fDeviceLinkLock; 118 }; 119 120 } // namespace skgpu::graphite 121 122 #endif // skgpu_graphite_Image_Base_Graphite_DEFINED 123