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