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