gfx/angle/src/libEGL/Display.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 //
     2 // Copyright (c) 2002-2013 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 //
     7 // Display.cpp: Implements 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.
    11 #include "libEGL/Display.h"
    13 #include <algorithm>
    14 #include <map>
    15 #include <vector>
    17 #include "common/debug.h"
    18 #include "libGLESv2/mathutil.h"
    19 #include "libGLESv2/main.h"
    20 #include "libGLESv2/Context.h"
    21 #include "libGLESv2/renderer/SwapChain.h"
    23 #include "libEGL/main.h"
    24 #include "libEGL/Surface.h"
    26 namespace egl
    27 {
    28 namespace
    29 {
    30     typedef std::map<EGLNativeDisplayType, Display*> DisplayMap; 
    31     DisplayMap displays;
    32 }
    34 egl::Display *Display::getDisplay(EGLNativeDisplayType displayId)
    35 {
    36     if (displays.find(displayId) != displays.end())
    37     {
    38         return displays[displayId];
    39     }
    41     // FIXME: Check if displayId is a valid display device context
    43     egl::Display *display = new egl::Display(displayId, (HDC)displayId);
    45     displays[displayId] = display;
    46     return display;
    47 }
    49 Display::Display(EGLNativeDisplayType displayId, HDC deviceContext) : mDc(deviceContext)
    50 {
    51     mDisplayId = displayId;
    52     mRenderer = NULL;
    53 }
    55 Display::~Display()
    56 {
    57     terminate();
    59     DisplayMap::iterator thisDisplay = displays.find(mDisplayId);
    61     if (thisDisplay != displays.end())
    62     {
    63         displays.erase(thisDisplay);
    64     }
    65 }
    67 bool Display::initialize()
    68 {
    69     if (isInitialized())
    70     {
    71         return true;
    72     }
    74     mRenderer = glCreateRenderer(this, mDc, mDisplayId);
    76     if (!mRenderer)
    77     {
    78         terminate();
    79         return error(EGL_NOT_INITIALIZED, false);
    80     }
    82     EGLint minSwapInterval = mRenderer->getMinSwapInterval();
    83     EGLint maxSwapInterval = mRenderer->getMaxSwapInterval();
    84     EGLint maxTextureWidth = mRenderer->getMaxTextureWidth();
    85     EGLint maxTextureHeight = mRenderer->getMaxTextureHeight();
    87     rx::ConfigDesc *descList;
    88     int numConfigs = mRenderer->generateConfigs(&descList);
    89     ConfigSet configSet;
    91     for (int i = 0; i < numConfigs; ++i)
    92         configSet.add(descList[i], minSwapInterval, maxSwapInterval,
    93                       maxTextureWidth, maxTextureHeight);
    95     // Give the sorted configs a unique ID and store them internally
    96     EGLint index = 1;
    97     for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
    98     {
    99         Config configuration = *config;
   100         configuration.mConfigID = index;
   101         index++;
   103         mConfigSet.mSet.insert(configuration);
   104     }
   106     mRenderer->deleteConfigs(descList);
   107     descList = NULL;
   109     if (!isInitialized())
   110     {
   111         terminate();
   112         return false;
   113     }
   115     initExtensionString();
   116     initVendorString();
   118     return true;
   119 }
   121 void Display::terminate()
   122 {
   123     while (!mSurfaceSet.empty())
   124     {
   125         destroySurface(*mSurfaceSet.begin());
   126     }
   128     while (!mContextSet.empty())
   129     {
   130         destroyContext(*mContextSet.begin());
   131     }
   133     glDestroyRenderer(mRenderer);
   134     mRenderer = NULL;
   135 }
   137 bool Display::getConfigs(EGLConfig *configs, const EGLint *attribList, EGLint configSize, EGLint *numConfig)
   138 {
   139     return mConfigSet.getConfigs(configs, attribList, configSize, numConfig);
   140 }
   142 bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
   143 {
   144     const egl::Config *configuration = mConfigSet.get(config);
   146     switch (attribute)
   147     {
   148       case EGL_BUFFER_SIZE:               *value = configuration->mBufferSize;             break;
   149       case EGL_ALPHA_SIZE:                *value = configuration->mAlphaSize;              break;
   150       case EGL_BLUE_SIZE:                 *value = configuration->mBlueSize;               break;
   151       case EGL_GREEN_SIZE:                *value = configuration->mGreenSize;              break;
   152       case EGL_RED_SIZE:                  *value = configuration->mRedSize;                break;
   153       case EGL_DEPTH_SIZE:                *value = configuration->mDepthSize;              break;
   154       case EGL_STENCIL_SIZE:              *value = configuration->mStencilSize;            break;
   155       case EGL_CONFIG_CAVEAT:             *value = configuration->mConfigCaveat;           break;
   156       case EGL_CONFIG_ID:                 *value = configuration->mConfigID;               break;
   157       case EGL_LEVEL:                     *value = configuration->mLevel;                  break;
   158       case EGL_NATIVE_RENDERABLE:         *value = configuration->mNativeRenderable;       break;
   159       case EGL_NATIVE_VISUAL_TYPE:        *value = configuration->mNativeVisualType;       break;
   160       case EGL_SAMPLES:                   *value = configuration->mSamples;                break;
   161       case EGL_SAMPLE_BUFFERS:            *value = configuration->mSampleBuffers;          break;
   162       case EGL_SURFACE_TYPE:              *value = configuration->mSurfaceType;            break;
   163       case EGL_TRANSPARENT_TYPE:          *value = configuration->mTransparentType;        break;
   164       case EGL_TRANSPARENT_BLUE_VALUE:    *value = configuration->mTransparentBlueValue;   break;
   165       case EGL_TRANSPARENT_GREEN_VALUE:   *value = configuration->mTransparentGreenValue;  break;
   166       case EGL_TRANSPARENT_RED_VALUE:     *value = configuration->mTransparentRedValue;    break;
   167       case EGL_BIND_TO_TEXTURE_RGB:       *value = configuration->mBindToTextureRGB;       break;
   168       case EGL_BIND_TO_TEXTURE_RGBA:      *value = configuration->mBindToTextureRGBA;      break;
   169       case EGL_MIN_SWAP_INTERVAL:         *value = configuration->mMinSwapInterval;        break;
   170       case EGL_MAX_SWAP_INTERVAL:         *value = configuration->mMaxSwapInterval;        break;
   171       case EGL_LUMINANCE_SIZE:            *value = configuration->mLuminanceSize;          break;
   172       case EGL_ALPHA_MASK_SIZE:           *value = configuration->mAlphaMaskSize;          break;
   173       case EGL_COLOR_BUFFER_TYPE:         *value = configuration->mColorBufferType;        break;
   174       case EGL_RENDERABLE_TYPE:           *value = configuration->mRenderableType;         break;
   175       case EGL_MATCH_NATIVE_PIXMAP:       *value = false; UNIMPLEMENTED();                 break;
   176       case EGL_CONFORMANT:                *value = configuration->mConformant;             break;
   177       case EGL_MAX_PBUFFER_WIDTH:         *value = configuration->mMaxPBufferWidth;        break;
   178       case EGL_MAX_PBUFFER_HEIGHT:        *value = configuration->mMaxPBufferHeight;       break;
   179       case EGL_MAX_PBUFFER_PIXELS:        *value = configuration->mMaxPBufferPixels;       break;
   180       default:
   181         return false;
   182     }
   184     return true;
   185 }
   189 EGLSurface Display::createWindowSurface(HWND window, EGLConfig config, const EGLint *attribList)
   190 {
   191     const Config *configuration = mConfigSet.get(config);
   192     EGLint postSubBufferSupported = EGL_FALSE;
   194     if (attribList)
   195     {
   196         while (*attribList != EGL_NONE)
   197         {
   198             switch (attribList[0])
   199             {
   200               case EGL_RENDER_BUFFER:
   201                 switch (attribList[1])
   202                 {
   203                   case EGL_BACK_BUFFER:
   204                     break;
   205                   case EGL_SINGLE_BUFFER:
   206                     return error(EGL_BAD_MATCH, EGL_NO_SURFACE);   // Rendering directly to front buffer not supported
   207                   default:
   208                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   209                 }
   210                 break;
   211               case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
   212                 postSubBufferSupported = attribList[1];
   213                 break;
   214               case EGL_VG_COLORSPACE:
   215                 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
   216               case EGL_VG_ALPHA_FORMAT:
   217                 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
   218               default:
   219                 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   220             }
   222             attribList += 2;
   223         }
   224     }
   226     if (hasExistingWindowSurface(window))
   227     {
   228         return error(EGL_BAD_ALLOC, EGL_NO_SURFACE);
   229     }
   231     if (mRenderer->testDeviceLost(false))
   232     {
   233         if (!restoreLostDevice())
   234             return EGL_NO_SURFACE;
   235     }
   237     Surface *surface = new Surface(this, configuration, window, postSubBufferSupported);
   239     if (!surface->initialize())
   240     {
   241         delete surface;
   242         return EGL_NO_SURFACE;
   243     }
   245     mSurfaceSet.insert(surface);
   247     return success(surface);
   248 }
   250 EGLSurface Display::createOffscreenSurface(EGLConfig config, HANDLE shareHandle, const EGLint *attribList)
   251 {
   252     EGLint width = 0, height = 0;
   253     EGLenum textureFormat = EGL_NO_TEXTURE;
   254     EGLenum textureTarget = EGL_NO_TEXTURE;
   255     const Config *configuration = mConfigSet.get(config);
   257     if (attribList)
   258     {
   259         while (*attribList != EGL_NONE)
   260         {
   261             switch (attribList[0])
   262             {
   263               case EGL_WIDTH:
   264                 width = attribList[1];
   265                 break;
   266               case EGL_HEIGHT:
   267                 height = attribList[1];
   268                 break;
   269               case EGL_LARGEST_PBUFFER:
   270                 if (attribList[1] != EGL_FALSE)
   271                   UNIMPLEMENTED(); // FIXME
   272                 break;
   273               case EGL_TEXTURE_FORMAT:
   274                 switch (attribList[1])
   275                 {
   276                   case EGL_NO_TEXTURE:
   277                   case EGL_TEXTURE_RGB:
   278                   case EGL_TEXTURE_RGBA:
   279                     textureFormat = attribList[1];
   280                     break;
   281                   default:
   282                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   283                 }
   284                 break;
   285               case EGL_TEXTURE_TARGET:
   286                 switch (attribList[1])
   287                 {
   288                   case EGL_NO_TEXTURE:
   289                   case EGL_TEXTURE_2D:
   290                     textureTarget = attribList[1];
   291                     break;
   292                   default:
   293                     return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   294                 }
   295                 break;
   296               case EGL_MIPMAP_TEXTURE:
   297                 if (attribList[1] != EGL_FALSE)
   298                   return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   299                 break;
   300               case EGL_VG_COLORSPACE:
   301                 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
   302               case EGL_VG_ALPHA_FORMAT:
   303                 return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
   304               default:
   305                 return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   306             }
   308             attribList += 2;
   309         }
   310     }
   312     if (width < 0 || height < 0)
   313     {
   314         return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE);
   315     }
   317     if (width == 0 || height == 0)
   318     {
   319         return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   320     }
   322     if (textureFormat != EGL_NO_TEXTURE && !mRenderer->getNonPower2TextureSupport() && (!gl::isPow2(width) || !gl::isPow2(height)))
   323     {
   324         return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
   325     }
   327     if ((textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) ||
   328         (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE))
   329     {
   330         return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
   331     }
   333     if (!(configuration->mSurfaceType & EGL_PBUFFER_BIT))
   334     {
   335         return error(EGL_BAD_MATCH, EGL_NO_SURFACE);
   336     }
   338     if ((textureFormat == EGL_TEXTURE_RGB && configuration->mBindToTextureRGB != EGL_TRUE) ||
   339         (textureFormat == EGL_TEXTURE_RGBA && configuration->mBindToTextureRGBA != EGL_TRUE))
   340     {
   341         return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE);
   342     }
   344     if (mRenderer->testDeviceLost(false))
   345     {
   346         if (!restoreLostDevice())
   347             return EGL_NO_SURFACE;
   348     }
   350     Surface *surface = new Surface(this, configuration, shareHandle, width, height, textureFormat, textureTarget);
   352     if (!surface->initialize())
   353     {
   354         delete surface;
   355         return EGL_NO_SURFACE;
   356     }
   358     mSurfaceSet.insert(surface);
   360     return success(surface);
   361 }
   363 EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext, bool notifyResets, bool robustAccess)
   364 {
   365     if (!mRenderer)
   366     {
   367         return NULL;
   368     }
   369     else if (mRenderer->testDeviceLost(false))   // Lost device
   370     {
   371         if (!restoreLostDevice())
   372             return NULL;
   373     }
   375     gl::Context *context = glCreateContext(shareContext, mRenderer, notifyResets, robustAccess);
   376     mContextSet.insert(context);
   378     return context;
   379 }
   381 bool Display::restoreLostDevice()
   382 {
   383     for (ContextSet::iterator ctx = mContextSet.begin(); ctx != mContextSet.end(); ctx++)
   384     {
   385         if ((*ctx)->isResetNotificationEnabled())
   386             return false;   // If reset notifications have been requested, application must delete all contexts first
   387     }
   389     // Release surface resources to make the Reset() succeed
   390     for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
   391     {
   392         (*surface)->release();
   393     }
   395     if (!mRenderer->resetDevice())
   396     {
   397         return error(EGL_BAD_ALLOC, false);
   398     }
   400     // Restore any surfaces that may have been lost
   401     for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
   402     {
   403         (*surface)->resetSwapChain();
   404     }
   406     return true;
   407 }
   410 void Display::destroySurface(egl::Surface *surface)
   411 {
   412     delete surface;
   413     mSurfaceSet.erase(surface);
   414 }
   416 void Display::destroyContext(gl::Context *context)
   417 {
   418     glDestroyContext(context);
   419     mContextSet.erase(context);
   420 }
   422 void Display::notifyDeviceLost()
   423 {
   424     for (ContextSet::iterator context = mContextSet.begin(); context != mContextSet.end(); context++)
   425     {
   426         (*context)->markContextLost();
   427     }
   428     egl::error(EGL_CONTEXT_LOST);
   429 }
   431 void Display::recreateSwapChains()
   432 {
   433     for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
   434     {
   435         (*surface)->getSwapChain()->recreate();
   436     }
   437 }
   439 bool Display::isInitialized() const
   440 {
   441     return mRenderer != NULL && mConfigSet.size() > 0;
   442 }
   444 bool Display::isValidConfig(EGLConfig config)
   445 {
   446     return mConfigSet.get(config) != NULL;
   447 }
   449 bool Display::isValidContext(gl::Context *context)
   450 {
   451     return mContextSet.find(context) != mContextSet.end();
   452 }
   454 bool Display::isValidSurface(egl::Surface *surface)
   455 {
   456     return mSurfaceSet.find(surface) != mSurfaceSet.end();
   457 }
   459 bool Display::hasExistingWindowSurface(HWND window)
   460 {
   461     for (SurfaceSet::iterator surface = mSurfaceSet.begin(); surface != mSurfaceSet.end(); surface++)
   462     {
   463         if ((*surface)->getWindowHandle() == window)
   464         {
   465             return true;
   466         }
   467     }
   469     return false;
   470 }
   472 void Display::initExtensionString()
   473 {
   474     HMODULE swiftShader = GetModuleHandle(TEXT("swiftshader_d3d9.dll"));
   475     bool shareHandleSupported = mRenderer->getShareHandleSupport();
   477     mExtensionString = "";
   479     // Multi-vendor (EXT) extensions
   480     mExtensionString += "EGL_EXT_create_context_robustness ";
   482     // ANGLE-specific extensions
   483     if (shareHandleSupported)
   484     {
   485         mExtensionString += "EGL_ANGLE_d3d_share_handle_client_buffer ";
   486     }
   488     mExtensionString += "EGL_ANGLE_query_surface_pointer ";
   490     if (swiftShader)
   491     {
   492         mExtensionString += "EGL_ANGLE_software_display ";
   493     }
   495     if (shareHandleSupported)
   496     {
   497         mExtensionString += "EGL_ANGLE_surface_d3d_texture_2d_share_handle ";
   498     }
   500     if (mRenderer->getPostSubBufferSupport())
   501     {
   502         mExtensionString += "EGL_NV_post_sub_buffer";
   503     }
   505     std::string::size_type end = mExtensionString.find_last_not_of(' ');
   506     if (end != std::string::npos)
   507     {
   508         mExtensionString.resize(end+1);
   509     }
   510 }
   512 const char *Display::getExtensionString() const
   513 {
   514     return mExtensionString.c_str();
   515 }
   517 void Display::initVendorString()
   518 {
   519     mVendorString = "Google Inc.";
   521     LUID adapterLuid = {0};
   523     if (mRenderer && mRenderer->getLUID(&adapterLuid))
   524     {
   525         char adapterLuidString[64];
   526         sprintf_s(adapterLuidString, sizeof(adapterLuidString), " (adapter LUID: %08x%08x)", adapterLuid.HighPart, adapterLuid.LowPart);
   528         mVendorString += adapterLuidString;
   529     }
   530 }
   532 const char *Display::getVendorString() const
   533 {
   534     return mVendorString.c_str();
   535 }
   537 }

mercurial