107 void initPromiseImage(
int index);
108 void recordAndPlayDDL();
109 bool isOnGPUThread()
const {
return SkGetThreadID() == fGpuThread; }
110 bool isOnMainThread()
const {
return SkGetThreadID() == fMainThread; }
112 Fuzz* fFuzz =
nullptr;
118 std::unique_ptr<SkExecutor> fRecordingExecutor =
121 SkTaskGroup fRecordingTaskGroup{*fRecordingExecutor};
124 std::queue<sk_sp<GrPromiseImageTexture>> fReusableTextures;
139 if (!fSurface || !fSurface->
characterize(&fSurfaceCharacterization)) {
144 fGpuTaskGroup.
add([&]{
148 fGpuTaskGroup.
wait();
150 this->initPromiseImage(
i);
156 if (!this->isOnGPUThread()) {
159 bool success = make_fuzz_t<bool>(fFuzz);
160 State prior = promiseImage.
fState.exchange(State::kTriedToFulfill, std::memory_order_relaxed);
161 if (prior != State::kInitial || promiseImage.
fTexture !=
nullptr) {
169 if (!fReusableTextures.empty() && make_fuzz_t<bool>(fFuzz)) {
170 promiseImage.
fTexture = std::move(fReusableTextures.front());
171 fReusableTextures.pop();
175 bool finishedBECreate =
false;
176 auto markFinished = [](
void* context) {
177 *(
bool*)context =
true;
190 "DDLFuzzer_FulFillPromiseImage");
192 while (!finishedBECreate) {
204 if (!this->isOnGPUThread()) {
208 State old = promiseImage.
fState.exchange(State::kDone, std::memory_order_relaxed);
209 if (promiseImage.
fDrawn && old != State::kTriedToFulfill) {
218 bool reuse = make_fuzz_t<bool>(fFuzz);
220 fReusableTextures.push(std::move(promiseImage.
fTexture));
237void DDLFuzzer::initPromiseImage(
int index) {
255void DDLFuzzer::recordAndPlayDDL() {
256 SkASSERT(!this->isOnGPUThread() && !this->isOnMainThread());
258 SkCanvas* canvas = recorder.getCanvas();
265 fPromiseImages[j].fDrawn =
true;
266 canvas->
drawImage(fPromiseImages[j].fImage, xOffset, 0);
269 fGpuTaskGroup.
add([ddl{std::move(ddl)},
this] {
282 fRecordingTaskGroup.
wait();
286 fGpuTaskGroup.
wait();
288 fGpuTaskGroup.
add([
this] {
289 while (!fReusableTextures.empty()) {
292 fReusableTextures.pop();
296 fPromiseImages.
reset(0);
298 fGpuTaskGroup.
wait();
DEF_FUZZ(DDLThreadingGL, fuzz)
static constexpr int kRecordingThreadCount
static sk_sp< GrPromiseImageTexture > fuzz_promise_image_fulfill(void *ctxIn)
T make_fuzz_t(Fuzz *fuzz)
static constexpr int kIterationCount
static void fuzz_promise_image_release(void *ctxIn)
static constexpr int kPromiseImageCount
static constexpr SkISize kPromiseImageSize
static constexpr int kPromiseImagesPerDDL
@ kTopLeft_GrSurfaceOrigin
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkASSERT_RELEASE(cond)
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
SkThreadID SkGetThreadID()
const SkThreadID kIllegalThreadID
DDLFuzzer & operator=(DDLFuzzer &)=delete
void releasePromiseImage(PromiseImageInfo &)
DDLFuzzer(DDLFuzzer &)=delete
sk_sp< GrPromiseImageTexture > fulfillPromiseImage(PromiseImageInfo &)
void nextRange(T *, Min, Max)
SK_API GrBackendFormat defaultBackendFormat(SkColorType, GrRenderable) const
void checkAsyncWorkCompletion()
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
void deleteBackendTexture(const GrBackendTexture &)
GrBackendTexture createBackendTexture(int width, int height, const GrBackendFormat &, skgpu::Mipmapped, GrRenderable, GrProtected=GrProtected::kNo, std::string_view label={})
sk_sp< GrContextThreadSafeProxy > threadSafeProxy()
GrBackendTexture backendTexture() const
static sk_sp< GrPromiseImageTexture > Make(const GrBackendTexture &backendTexture)
std::atomic< State > fState
PromiseImageInfo(PromiseImageInfo &)=delete
std::atomic< bool > fDrawn
PromiseImageInfo()=default
sk_sp< GrPromiseImageTexture > fTexture
PromiseImageInfo & operator=(PromiseImageInfo &)=delete
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
static sk_sp< SkColorSpace > MakeSRGB()
static std::unique_ptr< SkExecutor > MakeFIFOThreadPool(int threads=0, bool allowBorrowing=true)
bool characterize(GrSurfaceCharacterization *characterization) const
void batch(int N, std::function< void(int)> fn)
void add(std::function< void(void)> fn)
GrDirectContext * directContext() const
TestContext * testContext() const
ContextInfo getContextInfo(ContextType type, ContextOverrides=ContextOverrides::kNone)
skgpu::ContextType ContextType
void makeNotCurrent() const
void reset(T *ptr=nullptr)
void reset(size_t count=0)
SK_API sk_sp< SkImage > PromiseTextureFrom(skgpu::graphite::Recorder *, SkISize dimensions, const skgpu::graphite::TextureInfo &, const SkColorInfo &, skgpu::Origin origin, skgpu::graphite::Volatile, GraphitePromiseTextureFulfillProc, GraphitePromiseImageReleaseProc, GraphitePromiseTextureReleaseProc, GraphitePromiseImageContext, std::string_view label={})
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
SK_API bool DrawDDL(SkSurface *, sk_sp< const GrDeferredDisplayList > ddl)
constexpr int32_t width() const
constexpr int32_t height() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)