1/*
2 * Copyright 2016 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 GrDirectContextPriv_DEFINED
9#define GrDirectContextPriv_DEFINED
10
11#include "include/core/SkSpan.h"
12#include "include/core/SkSurface.h"
13#include "include/gpu/GrDirectContext.h"
14#include "src/gpu/BaseDevice.h"
15#include "src/gpu/GrRecordingContextPriv.h"
16
17class GrAtlasManager;
18class GrBackendFormat;
19class GrBackendRenderTarget;
20class GrImageInfo;
21class GrMemoryPool;
22class GrOnFlushCallbackObject;
23class GrRenderTargetProxy;
24class GrSemaphore;
25class GrSurfaceProxy;
26
27class SkDeferredDisplayList;
28class SkTaskGroup;
29
30/** Class that adds methods to GrDirectContext that are only intended for use internal to Skia.
31    This class is purely a privileged window into GrDirectContext. It should never have additional
32    data members or virtual methods. */
33class SK_API GrDirectContextPriv : public GrRecordingContextPriv {
34public:
35    GrDirectContext* context() { return static_cast<GrDirectContext*>(fContext); }
36    const GrDirectContext* context() const { return static_cast<const GrDirectContext*>(fContext); }
37
38    GrStrikeCache* getGrStrikeCache() { return this->context()->fStrikeCache.get(); }
39
40    /**
41     * Finalizes all pending reads and writes to the surfaces and also performs an MSAA resolves
42     * if necessary. The GrSurfaceProxy array is treated as a hint. If it is supplied the context
43     * will guarantee that the draws required for those proxies are flushed but it could do more.
44     * If no array is provided then all current work will be flushed.
45     *
46     * It is not necessary to call this before reading the render target via Skia/GrContext.
47     * GrContext will detect when it must perform a resolve before reading pixels back from the
48     * surface or using it as a texture.
49     */
50    GrSemaphoresSubmitted flushSurfaces(
51                SkSpan<GrSurfaceProxy*>,
52                SkSurface::BackendSurfaceAccess = SkSurface::BackendSurfaceAccess::kNoAccess,
53                const GrFlushInfo& = {},
54                const GrBackendSurfaceMutableState* newState = nullptr);
55
56    /** Version of above that flushes for a single proxy. Null is allowed. */
57    GrSemaphoresSubmitted flushSurface(
58                GrSurfaceProxy* proxy,
59                SkSurface::BackendSurfaceAccess access = SkSurface::BackendSurfaceAccess::kNoAccess,
60                const GrFlushInfo& info = {},
61                const GrBackendSurfaceMutableState* newState = nullptr) {
62        size_t size = proxy ? 1 : 0;
63        return this->flushSurfaces({&proxy, size}, access, info, newState);
64    }
65
66    /**
67     * Returns true if createPMToUPMEffect and createUPMToPMEffect will succeed. In other words,
68     * did we find a pair of round-trip preserving conversion effects?
69     */
70    bool validPMUPMConversionExists();
71
72    /**
73     * These functions create premul <-> unpremul effects, using specialized round-trip effects.
74     */
75    std::unique_ptr<GrFragmentProcessor> createPMToUPMEffect(std::unique_ptr<GrFragmentProcessor>);
76    std::unique_ptr<GrFragmentProcessor> createUPMToPMEffect(std::unique_ptr<GrFragmentProcessor>);
77
78    SkTaskGroup* getTaskGroup() { return this->context()->fTaskGroup.get(); }
79
80    GrResourceProvider* resourceProvider() { return this->context()->fResourceProvider.get(); }
81    const GrResourceProvider* resourceProvider() const {
82        return this->context()->fResourceProvider.get();
83    }
84
85    GrResourceCache* getResourceCache() { return this->context()->fResourceCache.get(); }
86
87    GrGpu* getGpu() { return this->context()->fGpu.get(); }
88    const GrGpu* getGpu() const { return this->context()->fGpu.get(); }
89
90    // This accessor should only ever be called by the GrOpFlushState.
91    GrAtlasManager* getAtlasManager() {
92        return this->context()->onGetAtlasManager();
93    }
94
95    // This accessor should only ever be called by the GrOpFlushState.
96    skgpu::v1::SmallPathAtlasMgr* getSmallPathAtlasMgr() {
97        return this->context()->onGetSmallPathAtlasMgr();
98    }
99
100    void createDDLTask(sk_sp<const SkDeferredDisplayList>,
101                       sk_sp<GrRenderTargetProxy> newDest,
102                       SkIPoint offset);
103
104    bool compile(const GrProgramDesc&, const GrProgramInfo&);
105
106    GrContextOptions::PersistentCache* getPersistentCache() {
107        return this->context()->fPersistentCache;
108    }
109
110    GrClientMappedBufferManager* clientMappedBufferManager() {
111        return this->context()->fMappedBufferManager.get();
112    }
113
114#if GR_TEST_UTILS
115    /** Reset GPU stats */
116    void resetGpuStats() const;
117
118    /** Prints cache stats to the string if GR_CACHE_STATS == 1. */
119    void dumpCacheStats(SkString*) const;
120    void dumpCacheStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
121    void printCacheStats() const;
122
123    /** Prints GPU stats to the string if GR_GPU_STATS == 1. */
124    void dumpGpuStats(SkString*) const;
125    void dumpGpuStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
126    void printGpuStats() const;
127
128    /** These are only active if GR_GPU_STATS == 1. */
129    void resetContextStats();
130    void dumpContextStats(SkString*) const;
131    void dumpContextStatsKeyValuePairs(SkTArray<SkString>* keys, SkTArray<double>* values) const;
132    void printContextStats() const;
133
134    /** Get pointer to atlas texture for given mask format. Note that this wraps an
135        actively mutating texture in an SkImage. This could yield unexpected results
136        if it gets cached or used more generally. */
137    sk_sp<SkImage> testingOnly_getFontAtlasImage(GrMaskFormat format, unsigned int index = 0);
138
139    void testingOnly_flushAndRemoveOnFlushCallbackObject(GrOnFlushCallbackObject*);
140#endif
141
142private:
143    explicit GrDirectContextPriv(GrDirectContext* dContext) : GrRecordingContextPriv(dContext) {}
144    // Required until C++17 copy elision
145    GrDirectContextPriv(const GrDirectContextPriv&) = default;
146    GrDirectContextPriv& operator=(const GrDirectContextPriv&) = delete;
147
148    // No taking addresses of this type.
149    const GrDirectContextPriv* operator&() const;
150    GrDirectContextPriv* operator&();
151
152    friend class GrDirectContext; // to construct/copy this type.
153
154    using INHERITED = GrRecordingContextPriv;
155};
156
157inline GrDirectContextPriv GrDirectContext::priv() { return GrDirectContextPriv(this); }
158
159// NOLINTNEXTLINE(readability-const-return-type)
160inline const GrDirectContextPriv GrDirectContext::priv() const {
161    return GrDirectContextPriv(const_cast<GrDirectContext*>(this));
162}
163
164#endif
165