• 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 <set>
16 #include <vector>
17 
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/Observer.h"
28 #include "libANGLE/Version.h"
29 #include "platform/Feature.h"
30 #include "platform/FrontendFeatures.h"
31 
32 namespace angle
33 {
34 class FrameCaptureShared;
35 }  // namespace angle
36 
37 namespace gl
38 {
39 class Context;
40 class TextureManager;
41 class SemaphoreManager;
42 }  // namespace gl
43 
44 namespace rx
45 {
46 class DisplayImpl;
47 class EGLImplFactory;
48 class ShareGroupImpl;
49 }  // namespace rx
50 
51 namespace egl
52 {
53 class Device;
54 class Image;
55 class Stream;
56 class Surface;
57 class Sync;
58 class Thread;
59 
60 using SurfaceSet = std::set<Surface *>;
61 
62 struct DisplayState final : private angle::NonCopyable
63 {
64     DisplayState(EGLNativeDisplayType nativeDisplayId);
65     ~DisplayState();
66 
67     EGLLabelKHR label;
68     SurfaceSet surfaceSet;
69     std::vector<std::string> featureOverridesEnabled;
70     std::vector<std::string> featureOverridesDisabled;
71     bool featuresAllDisabled;
72     EGLNativeDisplayType displayId;
73 };
74 
75 using ContextSet = std::set<gl::Context *>;
76 
77 class ShareGroup final : angle::NonCopyable
78 {
79   public:
80     ShareGroup(rx::EGLImplFactory *factory);
81 
82     void addRef();
83 
84     void release(const egl::Display *display);
85 
getImplementation()86     rx::ShareGroupImpl *getImplementation() const { return mImplementation; }
87 
generateFramebufferSerial()88     rx::Serial generateFramebufferSerial() { return mFramebufferSerialFactory.generate(); }
89 
getFrameCaptureShared()90     angle::FrameCaptureShared *getFrameCaptureShared() { return mFrameCaptureShared.get(); }
91 
92     void finishAllContexts();
93 
getContexts()94     const ContextSet &getContexts() const { return mContexts; }
95     void addSharedContext(gl::Context *context);
96     void removeSharedContext(gl::Context *context);
97 
getShareGroupContextCount()98     size_t getShareGroupContextCount() const { return mContexts.size(); }
99 
100   protected:
101     ~ShareGroup();
102 
103   private:
104     size_t mRefCount;
105     rx::ShareGroupImpl *mImplementation;
106     rx::SerialFactory mFramebufferSerialFactory;
107 
108     // Note: we use a raw pointer here so we can exclude frame capture sources from the build.
109     std::unique_ptr<angle::FrameCaptureShared> mFrameCaptureShared;
110 
111     // The list of contexts within the share group
112     ContextSet mContexts;
113 };
114 
115 // Constant coded here as a reasonable limit.
116 constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000;
117 
118 class Display final : public LabeledObject,
119                       public angle::ObserverInterface,
120                       public angle::NonCopyable
121 {
122   public:
123     ~Display() override;
124 
125     void setLabel(EGLLabelKHR label) override;
126     EGLLabelKHR getLabel() const override;
127 
128     // Observer implementation.
129     void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override;
130 
131     Error initialize();
132 
133     enum class TerminateReason
134     {
135         Api,
136         InternalCleanup,
137         ProcessExit,
138 
139         InvalidEnum,
140         EnumCount = InvalidEnum,
141     };
142     Error terminate(Thread *thread, TerminateReason terminateReason);
143     Error destroyInvalidEglObjects();
144     // Called before all display state dependent EGL functions. Backends can set up, for example,
145     // thread-specific backend state through this function. Not called for functions that do not
146     // need the state.
147     Error prepareForCall();
148     // Called on eglReleaseThread. Backends can tear down thread-specific backend state through
149     // this function.
150     Error releaseThread();
151 
152     static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap);
153     static Display *GetDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay,
154                                                 const AttributeMap &attribMap);
155     static Display *GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay);
156 
157     using EglDisplaySet = std::set<Display *>;
158     static EglDisplaySet GetEglDisplaySet();
159 
160     static const ClientExtensions &GetClientExtensions();
161     static const std::string &GetClientExtensionString();
162 
163     std::vector<const Config *> getConfigs(const AttributeMap &attribs) const;
164     std::vector<const Config *> chooseConfig(const AttributeMap &attribs) const;
165 
166     Error createWindowSurface(const Config *configuration,
167                               EGLNativeWindowType window,
168                               const AttributeMap &attribs,
169                               Surface **outSurface);
170     Error createPbufferSurface(const Config *configuration,
171                                const AttributeMap &attribs,
172                                Surface **outSurface);
173     Error createPbufferFromClientBuffer(const Config *configuration,
174                                         EGLenum buftype,
175                                         EGLClientBuffer clientBuffer,
176                                         const AttributeMap &attribs,
177                                         Surface **outSurface);
178     Error createPixmapSurface(const Config *configuration,
179                               NativePixmapType nativePixmap,
180                               const AttributeMap &attribs,
181                               Surface **outSurface);
182 
183     Error createImage(gl::Context *context,
184                       EGLenum target,
185                       EGLClientBuffer buffer,
186                       const AttributeMap &attribs,
187                       Image **outImage);
188 
189     Error createStream(const AttributeMap &attribs, Stream **outStream);
190 
191     Error createContext(const Config *configuration,
192                         gl::Context *shareContext,
193                         const EGLenum clientType,
194                         const AttributeMap &attribs,
195                         gl::Context **outContext);
196 
197     Error createSync(const gl::Context *currentContext,
198                      EGLenum type,
199                      const AttributeMap &attribs,
200                      Sync **outSync);
201 
202     Error makeCurrent(Thread *thread,
203                       gl::Context *previousContext,
204                       Surface *drawSurface,
205                       Surface *readSurface,
206                       gl::Context *context);
207 
208     Error destroySurface(Surface *surface);
209     void destroyImage(Image *image);
210     void destroyStream(Stream *stream);
211     Error destroyContext(Thread *thread, gl::Context *context);
212 
213     void destroySync(Sync *sync);
214 
215     bool isInitialized() const;
216     bool isValidConfig(const Config *config) const;
217     bool isValidContext(const gl::Context *context) const;
218     bool isValidSurface(const Surface *surface) const;
219     bool isValidImage(const Image *image) const;
220     bool isValidStream(const Stream *stream) const;
221     bool isValidSync(const Sync *sync) const;
222     bool isValidNativeWindow(EGLNativeWindowType window) const;
223 
224     Error validateClientBuffer(const Config *configuration,
225                                EGLenum buftype,
226                                EGLClientBuffer clientBuffer,
227                                const AttributeMap &attribs) const;
228     Error validateImageClientBuffer(const gl::Context *context,
229                                     EGLenum target,
230                                     EGLClientBuffer clientBuffer,
231                                     const egl::AttributeMap &attribs) const;
232     Error valdiatePixmap(const Config *config,
233                          EGLNativePixmapType pixmap,
234                          const AttributeMap &attributes) const;
235 
236     static bool isValidDisplay(const Display *display);
237     static bool isValidNativeDisplay(EGLNativeDisplayType display);
238     static bool hasExistingWindowSurface(EGLNativeWindowType window);
239 
240     bool isDeviceLost() const;
241     bool testDeviceLost();
242     void notifyDeviceLost();
243 
244     void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
areBlobCacheFuncsSet()245     bool areBlobCacheFuncsSet() const { return mBlobCache.areBlobCacheFuncsSet(); }
getBlobCache()246     BlobCache &getBlobCache() { return mBlobCache; }
247 
248     static EGLClientBuffer GetNativeClientBuffer(const struct AHardwareBuffer *buffer);
249     static Error CreateNativeClientBuffer(const egl::AttributeMap &attribMap,
250                                           EGLClientBuffer *eglClientBuffer);
251 
252     Error waitClient(const gl::Context *context);
253     Error waitNative(const gl::Context *context, EGLint engine);
254 
255     const Caps &getCaps() const;
256 
257     const DisplayExtensions &getExtensions() const;
258     const std::string &getExtensionString() const;
259     const std::string &getVendorString() const;
260     const std::string &getVersionString() const;
261 
262     std::string getBackendRendererDescription() const;
263     std::string getBackendVendorString() const;
264     std::string getBackendVersionString(bool includeFullVersion) const;
265 
266     EGLint programCacheGetAttrib(EGLenum attrib) const;
267     Error programCacheQuery(EGLint index,
268                             void *key,
269                             EGLint *keysize,
270                             void *binary,
271                             EGLint *binarysize);
272     Error programCachePopulate(const void *key,
273                                EGLint keysize,
274                                const void *binary,
275                                EGLint binarysize);
276     EGLint programCacheResize(EGLint limit, EGLenum mode);
277 
getAttributeMap()278     const AttributeMap &getAttributeMap() const { return mAttributeMap; }
getNativeDisplayId()279     EGLNativeDisplayType getNativeDisplayId() const { return mState.displayId; }
280 
getImplementation()281     rx::DisplayImpl *getImplementation() const { return mImplementation; }
282     Device *getDevice() const;
283     Surface *getWGLSurface() const;
getPlatform()284     EGLenum getPlatform() const { return mPlatform; }
285 
286     gl::Version getMaxSupportedESVersion() const;
287 
getState()288     const DisplayState &getState() const { return mState; }
289 
getFrontendFeatures()290     const angle::FrontendFeatures &getFrontendFeatures() { return mFrontendFeatures; }
291     void overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled);
292 
getFeatures()293     const angle::FeatureList &getFeatures() const { return mFeatures; }
294 
295     const char *queryStringi(const EGLint name, const EGLint index);
296 
297     EGLAttrib queryAttrib(const EGLint attribute);
298 
299     angle::ScratchBuffer requestScratchBuffer();
300     void returnScratchBuffer(angle::ScratchBuffer scratchBuffer);
301 
302     angle::ScratchBuffer requestZeroFilledBuffer();
303     void returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer);
304 
305     egl::Error handleGPUSwitch();
306     egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow);
307 
getDisplayGlobalMutex()308     std::mutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; }
getProgramCacheMutex()309     std::mutex &getProgramCacheMutex() { return mProgramCacheMutex; }
310 
311     // Installs LoggingAnnotator as the global DebugAnnotator, for back-ends that do not implement
312     // their own DebugAnnotator.
setGlobalDebugAnnotator()313     void setGlobalDebugAnnotator() { gl::InitializeDebugAnnotations(&mAnnotator); }
314 
315     bool supportsDmaBufFormat(EGLint format) const;
316     Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats);
317     Error queryDmaBufModifiers(EGLint format,
318                                EGLint max_modifiers,
319                                EGLuint64KHR *modifiers,
320                                EGLBoolean *external_only,
321                                EGLint *num_modifiers);
322 
323   private:
324     Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice);
325 
setAttributes(const AttributeMap & attribMap)326     void setAttributes(const AttributeMap &attribMap) { mAttributeMap = attribMap; }
327 
328     void setupDisplayPlatform(rx::DisplayImpl *impl);
329 
330     void updateAttribsFromEnvironment(const AttributeMap &attribMap);
331 
332     Error restoreLostDevice();
333     Error releaseContext(gl::Context *context, Thread *thread);
334 
335     void initDisplayExtensions();
336     void initVendorString();
337     void initVersionString();
338     void initializeFrontendFeatures();
339 
340     angle::ScratchBuffer requestScratchBufferImpl(std::vector<angle::ScratchBuffer> *bufferVector);
341     void returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,
342                                  std::vector<angle::ScratchBuffer> *bufferVector);
343 
344     DisplayState mState;
345     rx::DisplayImpl *mImplementation;
346     angle::ObserverBinding mGPUSwitchedBinding;
347 
348     AttributeMap mAttributeMap;
349 
350     ConfigSet mConfigSet;
351 
352     ContextSet mContextSet;
353 
354     typedef std::set<Image *> ImageSet;
355     ImageSet mImageSet;
356 
357     typedef std::set<Stream *> StreamSet;
358     StreamSet mStreamSet;
359 
360     typedef std::set<Sync *> SyncSet;
361     SyncSet mSyncSet;
362 
363     void destroyImageImpl(Image *image, ImageSet *images);
364     void destroyStreamImpl(Stream *stream, StreamSet *streams);
365     Error destroySurfaceImpl(Surface *surface, SurfaceSet *surfaces);
366     void destroySyncImpl(Sync *sync, SyncSet *syncs);
367 
368     std::mutex mInvalidEglObjectsMutex;
369     ImageSet mInvalidImageSet;
370     StreamSet mInvalidStreamSet;
371     SurfaceSet mInvalidSurfaceSet;
372     SyncSet mInvalidSyncSet;
373 
374     bool mInitialized;
375     bool mDeviceLost;
376 
377     Caps mCaps;
378 
379     DisplayExtensions mDisplayExtensions;
380     std::string mDisplayExtensionString;
381 
382     std::string mVendorString;
383     std::string mVersionString;
384 
385     Device *mDevice;
386     Surface *mSurface;
387     EGLenum mPlatform;
388     angle::LoggingAnnotator mAnnotator;
389 
390     gl::TextureManager *mTextureManager;
391     gl::SemaphoreManager *mSemaphoreManager;
392     BlobCache mBlobCache;
393     gl::MemoryProgramCache mMemoryProgramCache;
394     size_t mGlobalTextureShareGroupUsers;
395     size_t mGlobalSemaphoreShareGroupUsers;
396 
397     angle::FrontendFeatures mFrontendFeatures;
398 
399     angle::FeatureList mFeatures;
400 
401     std::mutex mScratchBufferMutex;
402     std::vector<angle::ScratchBuffer> mScratchBuffers;
403     std::vector<angle::ScratchBuffer> mZeroFilledBuffers;
404 
405     std::mutex mDisplayGlobalMutex;
406     std::mutex mProgramCacheMutex;
407 
408     bool mIsTerminated;
409 };
410 
411 }  // namespace egl
412 
413 #endif  // LIBANGLE_DISPLAY_H_
414