xref: /aosp_15_r20/external/angle/src/libANGLE/Display.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // Display.h: Defines the egl::Display class, representing the abstract
8 // display on which graphics are drawn. Implements EGLDisplay.
9 // [EGL 1.4] section 2.1.2 page 3.
10 
11 #ifndef LIBANGLE_DISPLAY_H_
12 #define LIBANGLE_DISPLAY_H_
13 
14 #include <mutex>
15 #include <vector>
16 
17 #include "common/SimpleMutex.h"
18 #include "common/WorkerThread.h"
19 #include "common/platform.h"
20 #include "libANGLE/AttributeMap.h"
21 #include "libANGLE/BlobCache.h"
22 #include "libANGLE/Caps.h"
23 #include "libANGLE/Config.h"
24 #include "libANGLE/Context.h"
25 #include "libANGLE/Debug.h"
26 #include "libANGLE/Error.h"
27 #include "libANGLE/LoggingAnnotator.h"
28 #include "libANGLE/MemoryProgramCache.h"
29 #include "libANGLE/MemoryShaderCache.h"
30 #include "libANGLE/Observer.h"
31 #include "libANGLE/ShareGroup.h"
32 #include "libANGLE/Version.h"
33 #include "platform/Feature.h"
34 #include "platform/autogen/FrontendFeatures_autogen.h"
35 
36 // Only DisplayCGL needs to be notified about an EGL call about to be made to prepare
37 // per-thread data. Disable Display::prepareForCall on other platforms for performance.
38 #if !defined(ANGLE_USE_DISPLAY_PREPARE_FOR_CALL)
39 #    if ANGLE_ENABLE_CGL
40 #        define ANGLE_USE_DISPLAY_PREPARE_FOR_CALL 1
41 #    else
42 #        define ANGLE_USE_DISPLAY_PREPARE_FOR_CALL 0
43 #    endif
44 #endif
45 
46 namespace angle
47 {
48 class FrameCaptureShared;
49 }  // namespace angle
50 
51 namespace gl
52 {
53 class Context;
54 class TextureManager;
55 class SemaphoreManager;
56 }  // namespace gl
57 
58 namespace rx
59 {
60 class DisplayImpl;
61 class EGLImplFactory;
62 }  // namespace rx
63 
64 namespace egl
65 {
66 class Device;
67 class Image;
68 class Stream;
69 class Surface;
70 class Sync;
71 class Thread;
72 
73 using SurfaceMap = angle::HashMap<GLuint, Surface *>;
74 using ThreadSet  = angle::HashSet<Thread *>;
75 
76 struct DisplayState final : private angle::NonCopyable
77 {
78     DisplayState(EGLNativeDisplayType nativeDisplayId);
79     ~DisplayState();
80 
81     void notifyDeviceLost() const;
82 
83     EGLLabelKHR label;
84     ContextMap contextMap;
85     mutable angle::SimpleMutex contextMapMutex;
86     SurfaceMap surfaceMap;
87     angle::FeatureOverrides featureOverrides;
88     EGLNativeDisplayType displayId;
89 
90     // Single-threaded and multithread pools for use by various parts of ANGLE, such as shader
91     // compilation.  These pools are internally synchronized.
92     std::shared_ptr<angle::WorkerThreadPool> singleThreadPool;
93     std::shared_ptr<angle::WorkerThreadPool> multiThreadPool;
94 
95     mutable bool deviceLost;
96 };
97 
98 // Constant coded here as a reasonable limit.
99 constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000;
100 
101 using ImageMap  = angle::HashMap<GLuint, Image *>;
102 using StreamSet = angle::HashSet<Stream *>;
103 using SyncMap   = angle::HashMap<GLuint, std::unique_ptr<Sync>>;
104 
105 class Display final : public LabeledObject,
106                       public angle::ObserverInterface,
107                       public angle::NonCopyable
108 {
109   public:
110     ~Display() override;
111 
112     void setLabel(EGLLabelKHR label) override;
113     EGLLabelKHR getLabel() const override;
114 
115     // Observer implementation.
116     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
117 
118     Error initialize();
119 
120     enum class TerminateReason
121     {
122         Api,
123         InternalCleanup,
124 
125         InvalidEnum,
126         EnumCount = InvalidEnum,
127     };
128     Error terminate(Thread *thread, TerminateReason terminateReason);
129 
130 #if ANGLE_USE_DISPLAY_PREPARE_FOR_CALL
131     // Called before all display state dependent EGL functions. Backends can set up, for example,
132     // thread-specific backend state through this function. Not called for functions that do not
133     // need the state.
134     Error prepareForCall();
135 #endif
136 
137     // Called on eglReleaseThread. Backends can tear down thread-specific backend state through
138     // this function.
139     Error releaseThread();
140 
141     static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
142     static Display *GetDisplayFromNativeDisplay(EGLenum platform,
143                                                 EGLNativeDisplayType nativeDisplay,
144                                                 const AttributeMap &attribMap);
145     static Display *GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay);
146 
147     using EglDisplaySet = angle::HashSet<Display *>;
148 
149     static const ClientExtensions &GetClientExtensions();
150     static const std::string &GetClientExtensionString();
151 
152     std::vector<const Config *> getConfigs(const AttributeMap &attribs) const;
153     std::vector<const Config *> chooseConfig(const AttributeMap &attribs) const;
154 
155     Error createWindowSurface(const Config *configuration,
156                               EGLNativeWindowType window,
157                               const AttributeMap &attribs,
158                               Surface **outSurface);
159     Error createPbufferSurface(const Config *configuration,
160                                const AttributeMap &attribs,
161                                Surface **outSurface);
162     Error createPbufferFromClientBuffer(const Config *configuration,
163                                         EGLenum buftype,
164                                         EGLClientBuffer clientBuffer,
165                                         const AttributeMap &attribs,
166                                         Surface **outSurface);
167     Error createPixmapSurface(const Config *configuration,
168                               NativePixmapType nativePixmap,
169                               const AttributeMap &attribs,
170                               Surface **outSurface);
171 
172     Error createImage(const gl::Context *context,
173                       EGLenum target,
174                       EGLClientBuffer buffer,
175                       const AttributeMap &attribs,
176                       Image **outImage);
177 
178     Error createStream(const AttributeMap &attribs, Stream **outStream);
179 
180     Error createContext(const Config *configuration,
181                         gl::Context *shareContext,
182                         const AttributeMap &attribs,
183                         gl::Context **outContext);
184 
185     Error createSync(const gl::Context *currentContext,
186                      EGLenum type,
187                      const AttributeMap &attribs,
188                      Sync **outSync);
189 
190     Error makeCurrent(Thread *thread,
191                       gl::Context *previousContext,
192                       Surface *drawSurface,
193                       Surface *readSurface,
194                       gl::Context *context);
195 
196     Error destroySurface(Surface *surface);
197     void destroyImage(Image *image);
198     void destroyStream(Stream *stream);
199     Error destroyContext(Thread *thread, gl::Context *context);
200 
201     void destroySync(Sync *sync);
202 
203     bool isInitialized() const;
204     bool isValidConfig(const Config *config) const;
205     bool isValidContext(gl::ContextID contextID) const;
206     bool isValidSurface(SurfaceID surfaceID) const;
207     bool isValidImage(ImageID imageID) const;
208     bool isValidStream(const Stream *stream) const;
209     bool isValidSync(SyncID sync) const;
210     bool isValidNativeWindow(EGLNativeWindowType window) const;
211 
212     Error validateClientBuffer(const Config *configuration,
213                                EGLenum buftype,
214                                EGLClientBuffer clientBuffer,
215                                const AttributeMap &attribs) const;
216     Error validateImageClientBuffer(const gl::Context *context,
217                                     EGLenum target,
218                                     EGLClientBuffer clientBuffer,
219                                     const egl::AttributeMap &attribs) const;
220     Error valdiatePixmap(const Config *config,
221                          EGLNativePixmapType pixmap,
222                          const AttributeMap &attributes) const;
223 
224     static bool isValidDisplay(const Display *display);
225     static bool isValidNativeDisplay(EGLNativeDisplayType display);
226     static bool hasExistingWindowSurface(EGLNativeWindowType window);
227 
228     bool isDeviceLost() const;
229     bool testDeviceLost();
230     void notifyDeviceLost();
231 
232     void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
areBlobCacheFuncsSet()233     bool areBlobCacheFuncsSet() const { return mBlobCache.areBlobCacheFuncsSet(); }
getBlobCache()234     BlobCache &getBlobCache() { return mBlobCache; }
235 
236     static EGLClientBuffer GetNativeClientBuffer(const struct AHardwareBuffer *buffer);
237     static Error CreateNativeClientBuffer(const egl::AttributeMap &attribMap,
238                                           EGLClientBuffer *eglClientBuffer);
239 
240     Error waitClient(const gl::Context *context);
241     Error waitNative(const gl::Context *context, EGLint engine);
242 
243     const Caps &getCaps() const;
244 
245     const DisplayExtensions &getExtensions() const;
246     const std::string &getExtensionString() const;
247     const std::string &getVendorString() const;
248     const std::string &getVersionString() const;
249     const std::string &getClientAPIString() const;
250 
251     std::string getBackendRendererDescription() const;
252     std::string getBackendVendorString() const;
253     std::string getBackendVersionString(bool includeFullVersion) const;
254 
255     EGLint programCacheGetAttrib(EGLenum attrib) const;
256     Error programCacheQuery(EGLint index,
257                             void *key,
258                             EGLint *keysize,
259                             void *binary,
260                             EGLint *binarysize);
261     Error programCachePopulate(const void *key,
262                                EGLint keysize,
263                                const void *binary,
264                                EGLint binarysize);
265     EGLint programCacheResize(EGLint limit, EGLenum mode);
266 
getAttributeMap()267     const AttributeMap &getAttributeMap() const { return mAttributeMap; }
getNativeDisplayId()268     EGLNativeDisplayType getNativeDisplayId() const { return mState.displayId; }
269 
getImplementation()270     rx::DisplayImpl *getImplementation() const { return mImplementation; }
271     Device *getDevice() const;
272     Surface *getWGLSurface() const;
getPlatform()273     EGLenum getPlatform() const { return mPlatform; }
274 
275     gl::Version getMaxSupportedESVersion() const;
276 
getState()277     const DisplayState &getState() const { return mState; }
278 
getFrontendFeatures()279     const angle::FrontendFeatures &getFrontendFeatures() { return mFrontendFeatures; }
280     void overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled);
281 
getFeatures()282     const angle::FeatureList &getFeatures() const { return mFeatures; }
283 
284     const char *queryStringi(const EGLint name, const EGLint index);
285 
286     EGLAttrib queryAttrib(const EGLint attribute);
287 
288     angle::ScratchBuffer requestScratchBuffer();
289     void returnScratchBuffer(angle::ScratchBuffer scratchBuffer);
290 
291     angle::ScratchBuffer requestZeroFilledBuffer();
292     void returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer);
293 
294     egl::Error handleGPUSwitch();
295     egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow);
296 
297     egl::Error waitUntilWorkScheduled();
298 
getDisplayGlobalMutex()299     angle::SimpleMutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; }
getProgramCacheMutex()300     angle::SimpleMutex &getProgramCacheMutex() { return mProgramCacheMutex; }
301 
getMemoryShaderCache()302     gl::MemoryShaderCache *getMemoryShaderCache() { return &mMemoryShaderCache; }
303 
304     // Installs LoggingAnnotator as the global DebugAnnotator, for back-ends that do not implement
305     // their own DebugAnnotator.
setGlobalDebugAnnotator()306     void setGlobalDebugAnnotator() { gl::InitializeDebugAnnotations(&mAnnotator); }
307 
308     bool supportsDmaBufFormat(EGLint format) const;
309     Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats);
310     Error queryDmaBufModifiers(EGLint format,
311                                EGLint max_modifiers,
312                                EGLuint64KHR *modifiers,
313                                EGLBoolean *external_only,
314                                EGLint *num_modifiers);
315 
getSingleThreadPool()316     std::shared_ptr<angle::WorkerThreadPool> getSingleThreadPool() const
317     {
318         return mState.singleThreadPool;
319     }
getMultiThreadPool()320     std::shared_ptr<angle::WorkerThreadPool> getMultiThreadPool() const
321     {
322         return mState.multiThreadPool;
323     }
324 
325     angle::ImageLoadContext getImageLoadContext() const;
326 
327     const gl::Context *getContext(gl::ContextID contextID) const;
328     const egl::Surface *getSurface(egl::SurfaceID surfaceID) const;
329     const egl::Image *getImage(egl::ImageID imageID) const;
330     const egl::Sync *getSync(egl::SyncID syncID) const;
331     gl::Context *getContext(gl::ContextID contextID);
332     egl::Surface *getSurface(egl::SurfaceID surfaceID);
333     egl::Image *getImage(egl::ImageID imageID);
334     egl::Sync *getSync(egl::SyncID syncID);
335 
getSyncsForCapture()336     const SyncMap &getSyncsForCapture() const { return mSyncMap; }
getImagesForCapture()337     const ImageMap &getImagesForCapture() const { return mImageMap; }
338 
339     // Initialize thread-local variables used by the Display and its backing implementations.  This
340     // includes:
341     //
342     // - The unlocked tail call to be run at the end of the entry point.
343     // - Scratch space for an egl::Error used by the backends (this is not used by all backends, and
344     //   access *must* be restricted to backends that use it).
345     //
346     static void InitTLS();
347     static angle::UnlockedTailCall *GetCurrentThreadUnlockedTailCall();
348     static Error *GetCurrentThreadErrorScratchSpace();
349 
350   private:
351     Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice);
352 
setAttributes(const AttributeMap & attribMap)353     void setAttributes(const AttributeMap &attribMap) { mAttributeMap = attribMap; }
354     void setupDisplayPlatform(rx::DisplayImpl *impl);
355 
356     Error restoreLostDevice();
357     Error releaseContext(gl::Context *context, Thread *thread);
358     Error releaseContextImpl(std::unique_ptr<gl::Context> &&context);
359     std::unique_ptr<gl::Context> eraseContextImpl(gl::Context *context, ContextMap *contexts);
360 
361     void initDisplayExtensions();
362     void initVendorString();
363     void initVersionString();
364     void initClientAPIString();
365     void initializeFrontendFeatures();
366 
367     angle::ScratchBuffer requestScratchBufferImpl(std::vector<angle::ScratchBuffer> *bufferVector);
368     void returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,
369                                  std::vector<angle::ScratchBuffer> *bufferVector);
370 
371     Error destroyInvalidEglObjects();
372 
373     DisplayState mState;
374     rx::DisplayImpl *mImplementation;
375     angle::ObserverBinding mGPUSwitchedBinding;
376 
377     AttributeMap mAttributeMap;
378 
379     ConfigSet mConfigSet;
380 
381     ImageMap mImageMap;
382     StreamSet mStreamSet;
383 
384     SyncMap mSyncMap;
385 
386     static constexpr size_t kMaxSyncPoolSizePerType = 32;
387     using SyncPool = angle::FixedVector<std::unique_ptr<Sync>, kMaxSyncPoolSizePerType>;
388     std::map<EGLenum, SyncPool> mSyncPools;
389 
390     void destroyImageImpl(Image *image, ImageMap *images);
391     void destroyStreamImpl(Stream *stream, StreamSet *streams);
392     Error destroySurfaceImpl(Surface *surface, SurfaceMap *surfaces);
393     void destroySyncImpl(SyncID syncId, SyncMap *syncs);
394 
395     ContextMap mInvalidContextMap;
396     ImageMap mInvalidImageMap;
397     StreamSet mInvalidStreamSet;
398     SurfaceMap mInvalidSurfaceMap;
399     SyncMap mInvalidSyncMap;
400 
401     bool mInitialized;
402 
403     Caps mCaps;
404 
405     DisplayExtensions mDisplayExtensions;
406     std::string mDisplayExtensionString;
407 
408     std::string mVendorString;
409     std::string mVersionString;
410     std::string mClientAPIString;
411 
412     Device *mDevice;
413     Surface *mSurface;
414     EGLenum mPlatform;
415     angle::LoggingAnnotator mAnnotator;
416 
417     // mManagersMutex protects mTextureManager and mSemaphoreManager
418     ContextMutex *mManagersMutex;
419     gl::TextureManager *mTextureManager;
420     gl::SemaphoreManager *mSemaphoreManager;
421 
422     BlobCache mBlobCache;
423     gl::MemoryProgramCache mMemoryProgramCache;
424     gl::MemoryShaderCache mMemoryShaderCache;
425     size_t mGlobalTextureShareGroupUsers;
426     size_t mGlobalSemaphoreShareGroupUsers;
427 
428     gl::HandleAllocator mImageHandleAllocator;
429     gl::HandleAllocator mSurfaceHandleAllocator;
430     gl::HandleAllocator mSyncHandleAllocator;
431 
432     angle::FrontendFeatures mFrontendFeatures;
433 
434     angle::FeatureList mFeatures;
435 
436     angle::SimpleMutex mScratchBufferMutex;
437     std::vector<angle::ScratchBuffer> mScratchBuffers;
438     std::vector<angle::ScratchBuffer> mZeroFilledBuffers;
439 
440     angle::SimpleMutex mDisplayGlobalMutex;
441     angle::SimpleMutex mProgramCacheMutex;
442 
443     bool mTerminatedByApi;
444 };
445 
446 }  // namespace egl
447 
448 #endif  // LIBANGLE_DISPLAY_H_
449