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 <vector> 16 17 #include "common/WorkerThread.h" 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/MemoryShaderCache.h" 28 #include "libANGLE/Observer.h" 29 #include "libANGLE/ShareGroup.h" 30 #include "libANGLE/Version.h" 31 #include "platform/Feature.h" 32 #include "platform/autogen/FrontendFeatures_autogen.h" 33 34 namespace angle 35 { 36 class FrameCaptureShared; 37 } // namespace angle 38 39 namespace gl 40 { 41 class Context; 42 class TextureManager; 43 class SemaphoreManager; 44 } // namespace gl 45 46 namespace rx 47 { 48 class DisplayImpl; 49 class EGLImplFactory; 50 } // namespace rx 51 52 namespace egl 53 { 54 class Device; 55 class Image; 56 class Stream; 57 class Surface; 58 class Sync; 59 class Thread; 60 61 using SurfaceMap = angle::HashMap<GLuint, Surface *>; 62 using ThreadSet = angle::HashSet<Thread *>; 63 64 struct DisplayState final : private angle::NonCopyable 65 { 66 DisplayState(EGLNativeDisplayType nativeDisplayId); 67 ~DisplayState(); 68 69 EGLLabelKHR label; 70 ContextMap contextMap; 71 SurfaceMap surfaceMap; 72 std::vector<std::string> featureOverridesEnabled; 73 std::vector<std::string> featureOverridesDisabled; 74 bool featuresAllDisabled; 75 EGLNativeDisplayType displayId; 76 }; 77 78 // Constant coded here as a reasonable limit. 79 constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000; 80 81 using ImageMap = angle::HashMap<GLuint, Image *>; 82 using StreamSet = angle::HashSet<Stream *>; 83 using SyncMap = angle::HashMap<GLuint, Sync *>; 84 85 class Display final : public LabeledObject, 86 public angle::ObserverInterface, 87 public angle::NonCopyable 88 { 89 public: 90 ~Display() override; 91 92 void setLabel(EGLLabelKHR label) override; 93 EGLLabelKHR getLabel() const override; 94 95 // Observer implementation. 96 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 97 98 Error initialize(); 99 100 enum class TerminateReason 101 { 102 Api, 103 InternalCleanup, 104 NoActiveThreads, 105 106 InvalidEnum, 107 EnumCount = InvalidEnum, 108 }; 109 Error terminate(Thread *thread, TerminateReason terminateReason); 110 // Called before all display state dependent EGL functions. Backends can set up, for example, 111 // thread-specific backend state through this function. Not called for functions that do not 112 // need the state. 113 Error prepareForCall(); 114 // Called on eglReleaseThread. Backends can tear down thread-specific backend state through 115 // this function. 116 Error releaseThread(); 117 118 // Helpers to maintain active thread set to assist with freeing invalid EGL objects. 119 void addActiveThread(Thread *thread); 120 void threadCleanup(Thread *thread); 121 getSharedContextMutexManager()122 ContextMutexManager *getSharedContextMutexManager() const 123 { 124 return mSharedContextMutexManager.get(); 125 } 126 127 static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap); 128 static Display *GetDisplayFromNativeDisplay(EGLenum platform, 129 EGLNativeDisplayType nativeDisplay, 130 const AttributeMap &attribMap); 131 static Display *GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay); 132 133 using EglDisplaySet = angle::HashSet<Display *>; 134 static EglDisplaySet GetEglDisplaySet(); 135 136 static const ClientExtensions &GetClientExtensions(); 137 static const std::string &GetClientExtensionString(); 138 139 std::vector<const Config *> getConfigs(const AttributeMap &attribs) const; 140 std::vector<const Config *> chooseConfig(const AttributeMap &attribs) const; 141 142 Error createWindowSurface(const Config *configuration, 143 EGLNativeWindowType window, 144 const AttributeMap &attribs, 145 Surface **outSurface); 146 Error createPbufferSurface(const Config *configuration, 147 const AttributeMap &attribs, 148 Surface **outSurface); 149 Error createPbufferFromClientBuffer(const Config *configuration, 150 EGLenum buftype, 151 EGLClientBuffer clientBuffer, 152 const AttributeMap &attribs, 153 Surface **outSurface); 154 Error createPixmapSurface(const Config *configuration, 155 NativePixmapType nativePixmap, 156 const AttributeMap &attribs, 157 Surface **outSurface); 158 159 Error createImage(const gl::Context *context, 160 EGLenum target, 161 EGLClientBuffer buffer, 162 const AttributeMap &attribs, 163 Image **outImage); 164 165 Error createStream(const AttributeMap &attribs, Stream **outStream); 166 167 Error createContext(const Config *configuration, 168 gl::Context *shareContext, 169 const EGLenum clientType, 170 const AttributeMap &attribs, 171 gl::Context **outContext); 172 173 Error createSync(const gl::Context *currentContext, 174 EGLenum type, 175 const AttributeMap &attribs, 176 Sync **outSync); 177 178 Error makeCurrent(Thread *thread, 179 gl::Context *previousContext, 180 Surface *drawSurface, 181 Surface *readSurface, 182 gl::Context *context); 183 184 Error destroySurface(Surface *surface); 185 void destroyImage(Image *image); 186 void destroyStream(Stream *stream); 187 Error destroyContext(Thread *thread, gl::Context *context); 188 189 void destroySync(Sync *sync); 190 191 bool isInitialized() const; 192 bool isValidConfig(const Config *config) const; 193 bool isValidContext(gl::ContextID contextID) const; 194 bool isValidSurface(SurfaceID surfaceID) const; 195 bool isValidImage(ImageID imageID) const; 196 bool isValidStream(const Stream *stream) const; 197 bool isValidSync(SyncID sync) const; 198 bool isValidNativeWindow(EGLNativeWindowType window) const; 199 200 Error validateClientBuffer(const Config *configuration, 201 EGLenum buftype, 202 EGLClientBuffer clientBuffer, 203 const AttributeMap &attribs) const; 204 Error validateImageClientBuffer(const gl::Context *context, 205 EGLenum target, 206 EGLClientBuffer clientBuffer, 207 const egl::AttributeMap &attribs) const; 208 Error valdiatePixmap(const Config *config, 209 EGLNativePixmapType pixmap, 210 const AttributeMap &attributes) const; 211 212 static bool isValidDisplay(const Display *display); 213 static bool isValidNativeDisplay(EGLNativeDisplayType display); 214 static bool hasExistingWindowSurface(EGLNativeWindowType window); 215 216 bool isDeviceLost() const; 217 bool testDeviceLost(); 218 void notifyDeviceLost(); 219 220 void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); areBlobCacheFuncsSet()221 bool areBlobCacheFuncsSet() const { return mBlobCache.areBlobCacheFuncsSet(); } getBlobCache()222 BlobCache &getBlobCache() { return mBlobCache; } 223 224 static EGLClientBuffer GetNativeClientBuffer(const struct AHardwareBuffer *buffer); 225 static Error CreateNativeClientBuffer(const egl::AttributeMap &attribMap, 226 EGLClientBuffer *eglClientBuffer); 227 228 Error waitClient(const gl::Context *context); 229 Error waitNative(const gl::Context *context, EGLint engine); 230 231 const Caps &getCaps() const; 232 233 const DisplayExtensions &getExtensions() const; 234 const std::string &getExtensionString() const; 235 const std::string &getVendorString() const; 236 const std::string &getVersionString() const; 237 const std::string &getClientAPIString() const; 238 239 std::string getBackendRendererDescription() const; 240 std::string getBackendVendorString() const; 241 std::string getBackendVersionString(bool includeFullVersion) const; 242 243 EGLint programCacheGetAttrib(EGLenum attrib) const; 244 Error programCacheQuery(EGLint index, 245 void *key, 246 EGLint *keysize, 247 void *binary, 248 EGLint *binarysize); 249 Error programCachePopulate(const void *key, 250 EGLint keysize, 251 const void *binary, 252 EGLint binarysize); 253 EGLint programCacheResize(EGLint limit, EGLenum mode); 254 getAttributeMap()255 const AttributeMap &getAttributeMap() const { return mAttributeMap; } getNativeDisplayId()256 EGLNativeDisplayType getNativeDisplayId() const { return mState.displayId; } 257 getImplementation()258 rx::DisplayImpl *getImplementation() const { return mImplementation; } 259 Device *getDevice() const; 260 Surface *getWGLSurface() const; getPlatform()261 EGLenum getPlatform() const { return mPlatform; } 262 263 gl::Version getMaxSupportedESVersion() const; 264 getState()265 const DisplayState &getState() const { return mState; } 266 getFrontendFeatures()267 const angle::FrontendFeatures &getFrontendFeatures() { return mFrontendFeatures; } 268 void overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled); 269 getFeatures()270 const angle::FeatureList &getFeatures() const { return mFeatures; } 271 272 const char *queryStringi(const EGLint name, const EGLint index); 273 274 EGLAttrib queryAttrib(const EGLint attribute); 275 276 angle::ScratchBuffer requestScratchBuffer(); 277 void returnScratchBuffer(angle::ScratchBuffer scratchBuffer); 278 279 angle::ScratchBuffer requestZeroFilledBuffer(); 280 void returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer); 281 282 egl::Error handleGPUSwitch(); 283 egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow); 284 285 egl::Error waitUntilWorkScheduled(); 286 getDisplayGlobalMutex()287 std::mutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; } getProgramCacheMutex()288 std::mutex &getProgramCacheMutex() { return mProgramCacheMutex; } 289 getMemoryShaderCache()290 gl::MemoryShaderCache *getMemoryShaderCache() { return &mMemoryShaderCache; } 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 bool supportsDmaBufFormat(EGLint format) const; 297 Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats); 298 Error queryDmaBufModifiers(EGLint format, 299 EGLint max_modifiers, 300 EGLuint64KHR *modifiers, 301 EGLBoolean *external_only, 302 EGLint *num_modifiers); 303 getSingleThreadPool()304 std::shared_ptr<angle::WorkerThreadPool> getSingleThreadPool() const 305 { 306 return mSingleThreadPool; 307 } getMultiThreadPool()308 std::shared_ptr<angle::WorkerThreadPool> getMultiThreadPool() const { return mMultiThreadPool; } 309 310 angle::ImageLoadContext getImageLoadContext() const; 311 312 const gl::Context *getContext(gl::ContextID contextID) const; 313 const egl::Surface *getSurface(egl::SurfaceID surfaceID) const; 314 const egl::Image *getImage(egl::ImageID imageID) const; 315 const egl::Sync *getSync(egl::SyncID syncID) const; 316 gl::Context *getContext(gl::ContextID contextID); 317 egl::Surface *getSurface(egl::SurfaceID surfaceID); 318 egl::Image *getImage(egl::ImageID imageID); 319 egl::Sync *getSync(egl::SyncID syncID); 320 getSyncsForCapture()321 const SyncMap &getSyncsForCapture() const { return mSyncMap; } 322 323 // Initialize thread-local variables used by the Display and its backing implementations. This 324 // includes: 325 // 326 // - The unlocked tail call to be run at the end of the entry point. 327 // - Scratch space for an egl::Error used by the backends (this is not used by all backends, and 328 // access *must* be restricted to backends that use it). 329 // 330 static void InitTLS(); 331 static angle::UnlockedTailCall *GetCurrentThreadUnlockedTailCall(); 332 static Error *GetCurrentThreadErrorScratchSpace(); 333 334 private: 335 Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice); 336 setAttributes(const AttributeMap & attribMap)337 void setAttributes(const AttributeMap &attribMap) { mAttributeMap = attribMap; } 338 void setupDisplayPlatform(rx::DisplayImpl *impl); 339 340 Error restoreLostDevice(); 341 Error releaseContext(gl::Context *context, Thread *thread); 342 Error releaseContextImpl(gl::Context *context, ContextMap *contexts); 343 344 void initDisplayExtensions(); 345 void initVendorString(); 346 void initVersionString(); 347 void initClientAPIString(); 348 void initializeFrontendFeatures(); 349 350 angle::ScratchBuffer requestScratchBufferImpl(std::vector<angle::ScratchBuffer> *bufferVector); 351 void returnScratchBufferImpl(angle::ScratchBuffer scratchBuffer, 352 std::vector<angle::ScratchBuffer> *bufferVector); 353 354 Error destroyInvalidEglObjects(); 355 356 DisplayState mState; 357 rx::DisplayImpl *mImplementation; 358 angle::ObserverBinding mGPUSwitchedBinding; 359 360 AttributeMap mAttributeMap; 361 362 ConfigSet mConfigSet; 363 364 ImageMap mImageMap; 365 StreamSet mStreamSet; 366 SyncMap mSyncMap; 367 368 void destroyImageImpl(Image *image, ImageMap *images); 369 void destroyStreamImpl(Stream *stream, StreamSet *streams); 370 Error destroySurfaceImpl(Surface *surface, SurfaceMap *surfaces); 371 void destroySyncImpl(Sync *sync, SyncMap *syncs); 372 373 ContextMap mInvalidContextMap; 374 ImageMap mInvalidImageMap; 375 StreamSet mInvalidStreamSet; 376 SurfaceMap mInvalidSurfaceMap; 377 SyncMap mInvalidSyncMap; 378 379 bool mInitialized; 380 bool mDeviceLost; 381 382 Caps mCaps; 383 384 DisplayExtensions mDisplayExtensions; 385 std::string mDisplayExtensionString; 386 387 std::string mVendorString; 388 std::string mVersionString; 389 std::string mClientAPIString; 390 391 Device *mDevice; 392 Surface *mSurface; 393 EGLenum mPlatform; 394 angle::LoggingAnnotator mAnnotator; 395 396 std::unique_ptr<ContextMutexManager> mSharedContextMutexManager; 397 398 // mManagersMutex protects mTextureManager and mSemaphoreManager 399 ContextMutex *mManagersMutex; 400 gl::TextureManager *mTextureManager; 401 gl::SemaphoreManager *mSemaphoreManager; 402 403 BlobCache mBlobCache; 404 gl::MemoryProgramCache mMemoryProgramCache; 405 gl::MemoryShaderCache mMemoryShaderCache; 406 size_t mGlobalTextureShareGroupUsers; 407 size_t mGlobalSemaphoreShareGroupUsers; 408 409 gl::HandleAllocator mImageHandleAllocator; 410 gl::HandleAllocator mSurfaceHandleAllocator; 411 gl::HandleAllocator mSyncHandleAllocator; 412 413 angle::FrontendFeatures mFrontendFeatures; 414 415 angle::FeatureList mFeatures; 416 417 std::mutex mScratchBufferMutex; 418 std::vector<angle::ScratchBuffer> mScratchBuffers; 419 std::vector<angle::ScratchBuffer> mZeroFilledBuffers; 420 421 std::mutex mDisplayGlobalMutex; 422 std::mutex mProgramCacheMutex; 423 424 bool mTerminatedByApi; 425 ThreadSet mActiveThreads; 426 427 // Single-threaded and multithread pools for use by various parts of ANGLE, such as shader 428 // compilation. These pools are internally synchronized. 429 std::shared_ptr<angle::WorkerThreadPool> mSingleThreadPool; 430 std::shared_ptr<angle::WorkerThreadPool> mMultiThreadPool; 431 }; 432 433 } // namespace egl 434 435 #endif // LIBANGLE_DISPLAY_H_ 436