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     void destroySync(Sync *sync);
184 
185     bool isInitialized() const;
186     bool isValidConfig(const Config *config) const;
187     bool isValidContext(const gl::Context *context) const;
188     bool isValidSurface(const Surface *surface) const;
189     bool isValidImage(const Image *image) const;
190     bool isValidStream(const Stream *stream) const;
191     bool isValidSync(const Sync *sync) const;
192     bool isValidNativeWindow(EGLNativeWindowType window) const;
193 
194     Error validateClientBuffer(const Config *configuration,
195                                EGLenum buftype,
196                                EGLClientBuffer clientBuffer,
197                                const AttributeMap &attribs) const;
198     Error validateImageClientBuffer(const gl::Context *context,
199                                     EGLenum target,
200                                     EGLClientBuffer clientBuffer,
201                                     const egl::AttributeMap &attribs) const;
202     Error valdiatePixmap(Config *config,
203                          EGLNativePixmapType pixmap,
204                          const AttributeMap &attributes) const;
205 
206     static bool isValidDisplay(const Display *display);
207     static bool isValidNativeDisplay(EGLNativeDisplayType display);
208     static bool hasExistingWindowSurface(EGLNativeWindowType window);
209 
210     bool isDeviceLost() const;
211     bool testDeviceLost();
212     void notifyDeviceLost();
213 
214     void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get);
areBlobCacheFuncsSet()215     bool areBlobCacheFuncsSet() const { return mBlobCache.areBlobCacheFuncsSet(); }
getBlobCache()216     BlobCache &getBlobCache() { return mBlobCache; }
217 
218     static EGLClientBuffer GetNativeClientBuffer(const struct AHardwareBuffer *buffer);
219     static Error CreateNativeClientBuffer(const egl::AttributeMap &attribMap,
220                                           EGLClientBuffer *eglClientBuffer);
221 
222     Error waitClient(const gl::Context *context);
223     Error waitNative(const gl::Context *context, EGLint engine);
224 
225     const Caps &getCaps() const;
226 
227     const DisplayExtensions &getExtensions() const;
228     const std::string &getExtensionString() const;
229     const std::string &getVendorString() const;
230 
231     EGLint programCacheGetAttrib(EGLenum attrib) const;
232     Error programCacheQuery(EGLint index,
233                             void *key,
234                             EGLint *keysize,
235                             void *binary,
236                             EGLint *binarysize);
237     Error programCachePopulate(const void *key,
238                                EGLint keysize,
239                                const void *binary,
240                                EGLint binarysize);
241     EGLint programCacheResize(EGLint limit, EGLenum mode);
242 
getAttributeMap()243     const AttributeMap &getAttributeMap() const { return mAttributeMap; }
getNativeDisplayId()244     EGLNativeDisplayType getNativeDisplayId() const { return mState.displayId; }
245 
getImplementation()246     rx::DisplayImpl *getImplementation() const { return mImplementation; }
247     Device *getDevice() const;
248     Surface *getWGLSurface() const;
getPlatform()249     EGLenum getPlatform() const { return mPlatform; }
250 
251     gl::Version getMaxSupportedESVersion() const;
252 
getState()253     const DisplayState &getState() const { return mState; }
254 
255     typedef std::set<gl::Context *> ContextSet;
getContextSet()256     const ContextSet &getContextSet() { return mContextSet; }
257 
getFrontendFeatures()258     const angle::FrontendFeatures &getFrontendFeatures() { return mFrontendFeatures; }
259     void overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled);
260 
getFeatures()261     const angle::FeatureList &getFeatures() const { return mFeatures; }
262 
263     const char *queryStringi(const EGLint name, const EGLint index);
264 
265     EGLAttrib queryAttrib(const EGLint attribute);
266 
267     angle::ScratchBuffer requestScratchBuffer();
268     void returnScratchBuffer(angle::ScratchBuffer scratchBuffer);
269 
270     angle::ScratchBuffer requestZeroFilledBuffer();
271     void returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer);
272 
273     egl::Error handleGPUSwitch();
274 
getDisplayGlobalMutex()275     std::mutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; }
getProgramCacheMutex()276     std::mutex &getProgramCacheMutex() { return mProgramCacheMutex; }
277 
278     // Installs LoggingAnnotator as the global DebugAnnotator, for back-ends that do not implement
279     // their own DebugAnnotator.
setGlobalDebugAnnotator()280     void setGlobalDebugAnnotator() { gl::InitializeDebugAnnotations(&mAnnotator); }
281 
282   private:
283     Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice);
284 
setAttributes(const AttributeMap & attribMap)285     void setAttributes(const AttributeMap &attribMap) { mAttributeMap = attribMap; }
286 
287     void setupDisplayPlatform(rx::DisplayImpl *impl);
288 
289     void updateAttribsFromEnvironment(const AttributeMap &attribMap);
290 
291     Error restoreLostDevice();
292     Error releaseContext(gl::Context *context);
293 
294     void initDisplayExtensions();
295     void initVendorString();
296     void initializeFrontendFeatures();
297 
298     angle::ScratchBuffer requestScratchBufferImpl(std::vector<angle::ScratchBuffer> *bufferVector);
299     void returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer,
300                                  std::vector<angle::ScratchBuffer> *bufferVector);
301 
302     DisplayState mState;
303     rx::DisplayImpl *mImplementation;
304     angle::ObserverBinding mGPUSwitchedBinding;
305 
306     AttributeMap mAttributeMap;
307 
308     ConfigSet mConfigSet;
309 
310     ContextSet mContextSet;
311 
312     typedef std::set<Image *> ImageSet;
313     ImageSet mImageSet;
314 
315     typedef std::set<Stream *> StreamSet;
316     StreamSet mStreamSet;
317 
318     typedef std::set<Sync *> SyncSet;
319     SyncSet mSyncSet;
320 
321     bool mInitialized;
322     bool mDeviceLost;
323 
324     Caps mCaps;
325 
326     DisplayExtensions mDisplayExtensions;
327     std::string mDisplayExtensionString;
328 
329     std::string mVendorString;
330 
331     Device *mDevice;
332     Surface *mSurface;
333     EGLenum mPlatform;
334     angle::LoggingAnnotator mAnnotator;
335 
336     gl::TextureManager *mTextureManager;
337     gl::SemaphoreManager *mSemaphoreManager;
338     BlobCache mBlobCache;
339     gl::MemoryProgramCache mMemoryProgramCache;
340     size_t mGlobalTextureShareGroupUsers;
341     size_t mGlobalSemaphoreShareGroupUsers;
342 
343     angle::FrontendFeatures mFrontendFeatures;
344 
345     angle::FeatureList mFeatures;
346 
347     std::mutex mScratchBufferMutex;
348     std::vector<angle::ScratchBuffer> mScratchBuffers;
349     std::vector<angle::ScratchBuffer> mZeroFilledBuffers;
350 
351     std::mutex mDisplayGlobalMutex;
352     std::mutex mProgramCacheMutex;
353 };
354 
355 }  // namespace egl
356 
357 #endif  // LIBANGLE_DISPLAY_H_
358