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