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