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