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