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