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 needs 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_ENABLE_CGL 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 mutable angle::SimpleMutex contextMapMutex; 86 SurfaceMap surfaceMap; 87 angle::FeatureOverrides featureOverrides; 88 EGLNativeDisplayType displayId; 89 90 // Single-threaded and multithread pools for use by various parts of ANGLE, such as shader 91 // compilation. These pools are internally synchronized. 92 std::shared_ptr<angle::WorkerThreadPool> singleThreadPool; 93 std::shared_ptr<angle::WorkerThreadPool> multiThreadPool; 94 95 mutable bool deviceLost; 96 }; 97 98 // Constant coded here as a reasonable limit. 99 constexpr EGLAttrib kProgramCacheSizeAbsoluteMax = 0x4000000; 100 101 using ImageMap = angle::HashMap<GLuint, Image *>; 102 using StreamSet = angle::HashSet<Stream *>; 103 using SyncMap = angle::HashMap<GLuint, std::unique_ptr<Sync>>; 104 105 class Display final : public LabeledObject, 106 public angle::ObserverInterface, 107 public angle::NonCopyable 108 { 109 public: 110 ~Display() override; 111 112 void setLabel(EGLLabelKHR label) override; 113 EGLLabelKHR getLabel() const override; 114 115 // Observer implementation. 116 void onSubjectStateChange(angle::SubjectIndex index, angle::SubjectMessage message) override; 117 118 Error initialize(); 119 120 enum class TerminateReason 121 { 122 Api, 123 InternalCleanup, 124 125 InvalidEnum, 126 EnumCount = InvalidEnum, 127 }; 128 Error terminate(Thread *thread, TerminateReason terminateReason); 129 130 #if ANGLE_USE_DISPLAY_PREPARE_FOR_CALL 131 // Called before all display state dependent EGL functions. Backends can set up, for example, 132 // thread-specific backend state through this function. Not called for functions that do not 133 // need the state. 134 Error prepareForCall(); 135 #endif 136 137 // Called on eglReleaseThread. Backends can tear down thread-specific backend state through 138 // this function. 139 Error releaseThread(); 140 141 static Display *GetDisplayFromDevice(Device *device, const AttributeMap &attribMap); 142 static Display *GetDisplayFromNativeDisplay(EGLenum platform, 143 EGLNativeDisplayType nativeDisplay, 144 const AttributeMap &attribMap); 145 static Display *GetExistingDisplayFromNativeDisplay(EGLNativeDisplayType nativeDisplay); 146 147 using EglDisplaySet = angle::HashSet<Display *>; 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 AttributeMap &attribs, 183 gl::Context **outContext); 184 185 Error createSync(const gl::Context *currentContext, 186 EGLenum type, 187 const AttributeMap &attribs, 188 Sync **outSync); 189 190 Error makeCurrent(Thread *thread, 191 gl::Context *previousContext, 192 Surface *drawSurface, 193 Surface *readSurface, 194 gl::Context *context); 195 196 Error destroySurface(Surface *surface); 197 void destroyImage(Image *image); 198 void destroyStream(Stream *stream); 199 Error destroyContext(Thread *thread, gl::Context *context); 200 201 void destroySync(Sync *sync); 202 203 bool isInitialized() const; 204 bool isValidConfig(const Config *config) const; 205 bool isValidContext(gl::ContextID contextID) const; 206 bool isValidSurface(SurfaceID surfaceID) const; 207 bool isValidImage(ImageID imageID) const; 208 bool isValidStream(const Stream *stream) const; 209 bool isValidSync(SyncID sync) const; 210 bool isValidNativeWindow(EGLNativeWindowType window) const; 211 212 Error validateClientBuffer(const Config *configuration, 213 EGLenum buftype, 214 EGLClientBuffer clientBuffer, 215 const AttributeMap &attribs) const; 216 Error validateImageClientBuffer(const gl::Context *context, 217 EGLenum target, 218 EGLClientBuffer clientBuffer, 219 const egl::AttributeMap &attribs) const; 220 Error valdiatePixmap(const Config *config, 221 EGLNativePixmapType pixmap, 222 const AttributeMap &attributes) const; 223 224 static bool isValidDisplay(const Display *display); 225 static bool isValidNativeDisplay(EGLNativeDisplayType display); 226 static bool hasExistingWindowSurface(EGLNativeWindowType window); 227 228 bool isDeviceLost() const; 229 bool testDeviceLost(); 230 void notifyDeviceLost(); 231 232 void setBlobCacheFuncs(EGLSetBlobFuncANDROID set, EGLGetBlobFuncANDROID get); areBlobCacheFuncsSet()233 bool areBlobCacheFuncsSet() const { return mBlobCache.areBlobCacheFuncsSet(); } getBlobCache()234 BlobCache &getBlobCache() { return mBlobCache; } 235 236 static EGLClientBuffer GetNativeClientBuffer(const struct AHardwareBuffer *buffer); 237 static Error CreateNativeClientBuffer(const egl::AttributeMap &attribMap, 238 EGLClientBuffer *eglClientBuffer); 239 240 Error waitClient(const gl::Context *context); 241 Error waitNative(const gl::Context *context, EGLint engine); 242 243 const Caps &getCaps() const; 244 245 const DisplayExtensions &getExtensions() const; 246 const std::string &getExtensionString() const; 247 const std::string &getVendorString() const; 248 const std::string &getVersionString() const; 249 const std::string &getClientAPIString() const; 250 251 std::string getBackendRendererDescription() const; 252 std::string getBackendVendorString() const; 253 std::string getBackendVersionString(bool includeFullVersion) const; 254 255 EGLint programCacheGetAttrib(EGLenum attrib) const; 256 Error programCacheQuery(EGLint index, 257 void *key, 258 EGLint *keysize, 259 void *binary, 260 EGLint *binarysize); 261 Error programCachePopulate(const void *key, 262 EGLint keysize, 263 const void *binary, 264 EGLint binarysize); 265 EGLint programCacheResize(EGLint limit, EGLenum mode); 266 getAttributeMap()267 const AttributeMap &getAttributeMap() const { return mAttributeMap; } getNativeDisplayId()268 EGLNativeDisplayType getNativeDisplayId() const { return mState.displayId; } 269 getImplementation()270 rx::DisplayImpl *getImplementation() const { return mImplementation; } 271 Device *getDevice() const; 272 Surface *getWGLSurface() const; getPlatform()273 EGLenum getPlatform() const { return mPlatform; } 274 275 gl::Version getMaxSupportedESVersion() const; 276 getState()277 const DisplayState &getState() const { return mState; } 278 getFrontendFeatures()279 const angle::FrontendFeatures &getFrontendFeatures() { return mFrontendFeatures; } 280 void overrideFrontendFeatures(const std::vector<std::string> &featureNames, bool enabled); 281 getFeatures()282 const angle::FeatureList &getFeatures() const { return mFeatures; } 283 284 const char *queryStringi(const EGLint name, const EGLint index); 285 286 EGLAttrib queryAttrib(const EGLint attribute); 287 288 angle::ScratchBuffer requestScratchBuffer(); 289 void returnScratchBuffer(angle::ScratchBuffer scratchBuffer); 290 291 angle::ScratchBuffer requestZeroFilledBuffer(); 292 void returnZeroFilledBuffer(angle::ScratchBuffer zeroFilledBuffer); 293 294 egl::Error handleGPUSwitch(); 295 egl::Error forceGPUSwitch(EGLint gpuIDHigh, EGLint gpuIDLow); 296 297 egl::Error waitUntilWorkScheduled(); 298 getDisplayGlobalMutex()299 angle::SimpleMutex &getDisplayGlobalMutex() { return mDisplayGlobalMutex; } getProgramCacheMutex()300 angle::SimpleMutex &getProgramCacheMutex() { return mProgramCacheMutex; } 301 getMemoryShaderCache()302 gl::MemoryShaderCache *getMemoryShaderCache() { return &mMemoryShaderCache; } 303 304 // Installs LoggingAnnotator as the global DebugAnnotator, for back-ends that do not implement 305 // their own DebugAnnotator. setGlobalDebugAnnotator()306 void setGlobalDebugAnnotator() { gl::InitializeDebugAnnotations(&mAnnotator); } 307 308 bool supportsDmaBufFormat(EGLint format) const; 309 Error queryDmaBufFormats(EGLint max_formats, EGLint *formats, EGLint *num_formats); 310 Error queryDmaBufModifiers(EGLint format, 311 EGLint max_modifiers, 312 EGLuint64KHR *modifiers, 313 EGLBoolean *external_only, 314 EGLint *num_modifiers); 315 getSingleThreadPool()316 std::shared_ptr<angle::WorkerThreadPool> getSingleThreadPool() const 317 { 318 return mState.singleThreadPool; 319 } getMultiThreadPool()320 std::shared_ptr<angle::WorkerThreadPool> getMultiThreadPool() const 321 { 322 return mState.multiThreadPool; 323 } 324 325 angle::ImageLoadContext getImageLoadContext() const; 326 327 const gl::Context *getContext(gl::ContextID contextID) const; 328 const egl::Surface *getSurface(egl::SurfaceID surfaceID) const; 329 const egl::Image *getImage(egl::ImageID imageID) const; 330 const egl::Sync *getSync(egl::SyncID syncID) const; 331 gl::Context *getContext(gl::ContextID contextID); 332 egl::Surface *getSurface(egl::SurfaceID surfaceID); 333 egl::Image *getImage(egl::ImageID imageID); 334 egl::Sync *getSync(egl::SyncID syncID); 335 getSyncsForCapture()336 const SyncMap &getSyncsForCapture() const { return mSyncMap; } getImagesForCapture()337 const ImageMap &getImagesForCapture() const { return mImageMap; } 338 339 // Initialize thread-local variables used by the Display and its backing implementations. This 340 // includes: 341 // 342 // - The unlocked tail call to be run at the end of the entry point. 343 // - Scratch space for an egl::Error used by the backends (this is not used by all backends, and 344 // access *must* be restricted to backends that use it). 345 // 346 static void InitTLS(); 347 static angle::UnlockedTailCall *GetCurrentThreadUnlockedTailCall(); 348 static Error *GetCurrentThreadErrorScratchSpace(); 349 350 private: 351 Display(EGLenum platform, EGLNativeDisplayType displayId, Device *eglDevice); 352 setAttributes(const AttributeMap & attribMap)353 void setAttributes(const AttributeMap &attribMap) { mAttributeMap = attribMap; } 354 void setupDisplayPlatform(rx::DisplayImpl *impl); 355 356 Error restoreLostDevice(); 357 Error releaseContext(gl::Context *context, Thread *thread); 358 Error releaseContextImpl(std::unique_ptr<gl::Context> &&context); 359 std::unique_ptr<gl::Context> eraseContextImpl(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