Flutter Engine
The Flutter Engine
GrDeferredProxyUploader.h
Go to the documentation of this file.
1/*
2 * Copyright 2017 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 GrDeferredProxyUploader_DEFINED
9#define GrDeferredProxyUploader_DEFINED
10
14
17
18/**
19 * GrDeferredProxyUploader assists with threaded generation of textures. Currently used by both
20 * software clip masks, and the software path renderer. The calling code typically needs to store
21 * some additional data (T) for use on the worker thread. GrTDeferredProxyUploader allows storing
22 * such data. The common flow is:
23 *
24 * 1) A GrTDeferredProxyUploader is created, with some payload (eg an SkPath to draw).
25 * The uploader is owned by the proxy that it's going to populate.
26 * 2) A task is created with a pointer to the uploader. A worker thread executes that task, using
27 * the payload data to allocate and fill in the fPixels pixmap.
28 * 3) The worker thread calls signalAndFreeData(), which notifies the main thread that the pixmap
29 * is ready, and then deletes the payload data (which is no longer needed).
30 * 4) In parallel to 2-3, on the main thread... Some op is created that refers to the proxy. When
31 * that op is added to an op list, the op list retains a pointer to the "deferred" proxies.
32 * 5) At flush time, the op list ensures that the deferred proxies are instantiated, then calls
33 * scheduleUpload on those proxies, which calls scheduleUpload on the uploader (below).
34 * 6) scheduleUpload defers the upload even further, by adding an ASAPUpload to the flush.
35 * 7) When the ASAP upload happens, we wait to make sure that the pixels are marked ready
36 * (from step #3 on the worker thread). Then we perform the actual upload to the texture.
37 * Finally, we call resetDeferredUploader, which deletes the uploader object, causing fPixels
38 * to be freed.
39 */
41public:
42 GrDeferredProxyUploader() : fScheduledUpload(false), fWaited(false) {}
43
45 // In normal usage (i.e., through GrTDeferredProxyUploader) this will be redundant
46 this->wait();
47 }
48
49 void scheduleUpload(GrOpFlushState* flushState, GrTextureProxy* proxy) {
50 if (fScheduledUpload) {
51 // Multiple references to the owning proxy may have caused us to already execute
52 return;
53 }
54
55 auto uploadMask = [this, proxy](GrDeferredTextureUploadWritePixelsFn& writePixelsFn) {
56 this->wait();
57 GrColorType pixelColorType = SkColorTypeToGrColorType(this->fPixels.info().colorType());
58 // If the worker thread was unable to allocate pixels, this check will fail, and we'll
59 // end up drawing with an uninitialized mask texture, but at least we won't crash.
60 if (this->fPixels.addr()) {
61 writePixelsFn(proxy,
63 pixelColorType,
64 this->fPixels.addr(),
65 this->fPixels.rowBytes());
66 }
67 // Upload has finished, so tell the proxy to release this GrDeferredProxyUploader
69 };
70 flushState->addASAPUpload(std::move(uploadMask));
71 fScheduledUpload = true;
72 }
73
75 this->freeData();
76 fPixelsReady.signal();
77 }
78
79 SkAutoPixmapStorage* getPixels() { return &fPixels; }
80
81protected:
82 void wait() {
83 if (!fWaited) {
84 fPixelsReady.wait();
85 fWaited = true;
86 }
87 }
88
89private:
90 virtual void freeData() {}
91
92 SkAutoPixmapStorage fPixels;
93 SkSemaphore fPixelsReady;
94 bool fScheduledUpload;
95 bool fWaited;
96};
97
98template <typename T>
100public:
101 template <typename... Args>
103 : fData(std::make_unique<T>(std::forward<Args>(args)...)) {
104 }
105
107 // We need to wait here, so that we don't free fData before the worker thread is done
108 // with it. (This happens if the proxy is deleted early due to a full clear or failure
109 // of an op list to instantiate).
110 this->wait();
111 }
112
113 T& data() { return *fData; }
114
115private:
116 void freeData() override {
117 fData.reset();
118 }
119
120 std::unique_ptr<T> fData;
121};
122
123#endif
std::function< bool(GrTextureProxy *, SkIRect, GrColorType srcColorType, const void *, size_t rowBytes)> GrDeferredTextureUploadWritePixelsFn
GrColorType
Definition: GrTypesPriv.h:540
static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct)
Definition: GrTypesPriv.h:629
SkAutoPixmapStorage * getPixels()
void scheduleUpload(GrOpFlushState *flushState, GrTextureProxy *proxy)
skgpu::AtlasToken addASAPUpload(GrDeferredTextureUploadFn &&) final
GrTDeferredProxyUploader(Args &&... args)
GrTextureProxyPriv texPriv()
const SkImageInfo & info() const
Definition: SkPixmap.h:135
const void * addr() const
Definition: SkPixmap.h:153
SkISize dimensions() const
Definition: SkPixmap.h:171
void signal(int n=1)
Definition: SkSemaphore.h:56
void wait()
Definition: SkSemaphore.h:74
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
Definition: ref_ptr.h:256
#define T
Definition: precompiler.cc:65
static constexpr SkIRect MakeSize(const SkISize &size)
Definition: SkRect.h:66
SkColorType colorType() const
Definition: SkImageInfo.h:373