Flutter Engine
The Flutter Engine
GpuToolUtils.cpp
Go to the documentation of this file.
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
9
12
13#if defined(SK_GANESH)
19#endif
20
21#if defined(SK_GRAPHITE)
26#include "src/core/SkLRUCache.h"
27#endif
28
29
30namespace ToolUtils {
31
33 if (!orig) {
34 return nullptr;
35 }
36
37#if defined(SK_GANESH)
38 if (canvas->recordingContext() && canvas->recordingContext()->asDirectContext()) {
39 GrDirectContext* dContext = canvas->recordingContext()->asDirectContext();
40 const GrCaps* caps = dContext->priv().caps();
41
42 if (orig->width() >= caps->maxTextureSize() || orig->height() >= caps->maxTextureSize()) {
43 // Ganesh is able to tile large SkImage draws. Always forcing SkImages to be uploaded
44 // prevents this feature from being tested by our tools. For now, leave excessively
45 // large SkImages as bitmaps.
46 return orig;
47 }
48
49 return SkImages::TextureFromImage(dContext, orig);
50 }
51#endif
52#if defined(SK_GRAPHITE)
53 if (canvas->recorder()) {
54 return SkImages::TextureFromImage(canvas->recorder(), orig, {false});
55 }
56#endif
57 return orig;
58}
59
60#if defined(SK_GRAPHITE)
61
62// Currently, we give each new Recorder its own ImageProvider. This means we don't have to deal
63// w/ any threading issues.
64// TODO: We should probably have this class generate and report some cache stats
65// TODO: Hook up to listener system?
66// TODO: add testing of a single ImageProvider passed to multiple recorders
67class TestingImageProvider : public skgpu::graphite::ImageProvider {
68public:
69 TestingImageProvider() : fCache(kDefaultNumCachedImages) {}
70 ~TestingImageProvider() override {}
71
72 sk_sp<SkImage> findOrCreate(skgpu::graphite::Recorder* recorder,
73 const SkImage* image,
74 SkImage::RequiredProperties requiredProps) override {
75 if (!requiredProps.fMipmapped) {
76 // If no mipmaps are required, check to see if we have a mipmapped version anyway -
77 // since it can be used in that case.
78 // TODO: we could get fancy and, if ever a mipmapped key eclipsed a non-mipmapped
79 // key, we could remove the hidden non-mipmapped key/image from the cache.
80 ImageKey mipMappedKey(image, /* mipmapped= */ true);
81 auto result = fCache.find(mipMappedKey);
82 if (result) {
83 return *result;
84 }
85 }
86
87 ImageKey key(image, requiredProps.fMipmapped);
88
89 auto result = fCache.find(key);
90 if (result) {
91 return *result;
92 }
93
94 sk_sp<SkImage> newImage = SkImages::TextureFromImage(recorder, image, requiredProps);
95 if (!newImage) {
96 return nullptr;
97 }
98
99 result = fCache.insert(key, std::move(newImage));
101
102 return *result;
103 }
104
105private:
106 static constexpr int kDefaultNumCachedImages = 256;
107
108 class ImageKey {
109 public:
110 ImageKey(const SkImage* image, bool mipmapped) {
111 uint32_t flags = mipmapped ? 0x1 : 0x0;
113 fValues[kNumValues-1] = flags;
114 fValues[0] = SkChecksum::Hash32(&fValues[1], (kNumValues-1) * sizeof(uint32_t));
115 }
116
117 uint32_t hash() const { return fValues[0]; }
118
119 bool operator==(const ImageKey& other) const {
120 for (int i = 0; i < kNumValues; ++i) {
121 if (fValues[i] != other.fValues[i]) {
122 return false;
123 }
124 }
125
126 return true;
127 }
128 bool operator!=(const ImageKey& other) const { return !(*this == other); }
129
130 private:
131 static const int kNumValues = SkTiledImageUtils::kNumImageKeyValues + 2;
132
133 uint32_t fValues[kNumValues];
134 };
135
136 struct ImageHash {
137 size_t operator()(const ImageKey& key) const { return key.hash(); }
138 };
139
140 SkLRUCache<ImageKey, sk_sp<SkImage>, ImageHash> fCache;
141};
142
143skgpu::graphite::RecorderOptions CreateTestingRecorderOptions() {
145
146 options.fImageProvider.reset(new TestingImageProvider);
147
148 return options;
149}
150
151#endif // SK_GRAPHITE
152
153} // namespace ToolUtils
const char * options
#define SkASSERT(cond)
Definition: SkAssert.h:116
static uint32_t hash(const SkShaderBase::GradientInfo &v)
const GrCaps * caps() const
Definition: GrCaps.h:57
int maxTextureSize() const
Definition: GrCaps.h:229
virtual GrDirectContext * asDirectContext()
GrDirectContextPriv priv()
virtual GrRecordingContext * recordingContext() const
Definition: SkCanvas.cpp:1637
virtual skgpu::graphite::Recorder * recorder() const
Definition: SkCanvas.cpp:1641
int width() const
Definition: SkImage.h:285
int height() const
Definition: SkImage.h:291
FlutterSemanticsFlag flags
GAsyncResult * result
uint32_t Hash32(const void *data, size_t bytes, uint32_t seed)
Definition: SkChecksum.cpp:113
SK_API sk_sp< SkImage > TextureFromImage(GrDirectContext *, const SkImage *, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Budgeted=skgpu::Budgeted::kYes)
sk_sp< const SkImage > image
Definition: SkRecords.h:269
static constexpr int kNumImageKeyValues
SK_API void GetImageKeyValues(const SkImage *image, uint32_t keyValues[kNumImageKeyValues])
sk_sp< SkImage > MakeTextureImage(SkCanvas *canvas, sk_sp< SkImage > orig)
bool operator==(C p1, const scoped_nsprotocol< C > &p2)
bool operator!=(C p1, const scoped_nsprotocol< C > &p2)