tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DisplayD3D.cpp (14700B)


      1 //
      2 // Copyright 2014 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 // DisplayD3D.cpp: D3D implementation of egl::Display
      8 
      9 #include "libANGLE/renderer/d3d/DisplayD3D.h"
     10 
     11 #include <EGL/eglext.h>
     12 
     13 #include "libANGLE/Config.h"
     14 #include "libANGLE/Context.h"
     15 #include "libANGLE/Display.h"
     16 #include "libANGLE/Surface.h"
     17 #include "libANGLE/Thread.h"
     18 #include "libANGLE/histogram_macros.h"
     19 #include "libANGLE/renderer/d3d/DeviceD3D.h"
     20 #include "libANGLE/renderer/d3d/EGLImageD3D.h"
     21 #include "libANGLE/renderer/d3d/RendererD3D.h"
     22 #include "libANGLE/renderer/d3d/SurfaceD3D.h"
     23 #include "libANGLE/renderer/d3d/SwapChainD3D.h"
     24 
     25 #if !defined(ANGLE_DEFAULT_D3D11)
     26 // Enables use of the Direct3D 11 API for a default display, when available
     27 #    define ANGLE_DEFAULT_D3D11 1
     28 #endif
     29 
     30 namespace rx
     31 {
     32 
     33 using CreateRendererD3DFunction = RendererD3D *(*)(egl::Display *);
     34 
     35 egl::Error CreateRendererD3D(egl::Display *display, RendererD3D **outRenderer)
     36 {
     37    ASSERT(outRenderer != nullptr);
     38 
     39    std::vector<CreateRendererD3DFunction> rendererCreationFunctions;
     40 
     41    if (display->getPlatform() == EGL_PLATFORM_ANGLE_ANGLE)
     42    {
     43        const auto &attribMap              = display->getAttributeMap();
     44        EGLNativeDisplayType nativeDisplay = display->getNativeDisplayId();
     45 
     46        EGLint requestedDisplayType = static_cast<EGLint>(
     47            attribMap.get(EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE));
     48 
     49 #if defined(ANGLE_ENABLE_D3D11)
     50        const auto addD3D11 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
     51                              nativeDisplay == EGL_D3D11_ONLY_DISPLAY_ANGLE ||
     52                              requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
     53 #endif
     54 
     55 #if defined(ANGLE_ENABLE_D3D9)
     56        const auto addD3D9 = nativeDisplay == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE ||
     57                             requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
     58 #endif
     59 
     60 #if ANGLE_DEFAULT_D3D11
     61 #    if defined(ANGLE_ENABLE_D3D11)
     62        if (addD3D11)
     63        {
     64            rendererCreationFunctions.push_back(CreateRenderer11);
     65        }
     66 #    endif
     67 
     68 #    if defined(ANGLE_ENABLE_D3D9)
     69        if (addD3D9)
     70        {
     71            rendererCreationFunctions.push_back(CreateRenderer9);
     72        }
     73 #    endif
     74 #else
     75 #    if defined(ANGLE_ENABLE_D3D9)
     76        if (addD3D9)
     77        {
     78            rendererCreationFunctions.push_back(CreateRenderer9);
     79        }
     80 #    endif
     81 
     82 #    if defined(ANGLE_ENABLE_D3D11)
     83        if (addD3D11)
     84        {
     85            rendererCreationFunctions.push_back(CreateRenderer11);
     86        }
     87 #    endif
     88 #endif
     89 
     90        if (nativeDisplay != EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE &&
     91            nativeDisplay != EGL_D3D11_ONLY_DISPLAY_ANGLE &&
     92            requestedDisplayType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE)
     93        {
     94            // The default display is requested, try the D3D9 and D3D11 renderers, order them using
     95            // the definition of ANGLE_DEFAULT_D3D11
     96 #if ANGLE_DEFAULT_D3D11
     97 #    if defined(ANGLE_ENABLE_D3D11)
     98            rendererCreationFunctions.push_back(CreateRenderer11);
     99 #    endif
    100 #    if defined(ANGLE_ENABLE_D3D9)
    101            rendererCreationFunctions.push_back(CreateRenderer9);
    102 #    endif
    103 #else
    104 #    if defined(ANGLE_ENABLE_D3D9)
    105            rendererCreationFunctions.push_back(CreateRenderer9);
    106 #    endif
    107 #    if defined(ANGLE_ENABLE_D3D11)
    108            rendererCreationFunctions.push_back(CreateRenderer11);
    109 #    endif
    110 #endif
    111        }
    112    }
    113    else if (display->getPlatform() == EGL_PLATFORM_DEVICE_EXT)
    114    {
    115 #if defined(ANGLE_ENABLE_D3D11)
    116        if (display->getDevice()->getType() == EGL_D3D11_DEVICE_ANGLE)
    117        {
    118            rendererCreationFunctions.push_back(CreateRenderer11);
    119        }
    120 #endif
    121    }
    122    else
    123    {
    124        UNIMPLEMENTED();
    125    }
    126 
    127    for (size_t i = 0; i < rendererCreationFunctions.size(); i++)
    128    {
    129        RendererD3D *renderer = rendererCreationFunctions[i](display);
    130        egl::Error result     = renderer->initialize();
    131 
    132 #if defined(ANGLE_ENABLE_D3D11)
    133        if (renderer->getRendererClass() == RENDERER_D3D11)
    134        {
    135            ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D11_INIT_ERRORS);
    136            ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D11InitializeResult", result.getID(),
    137                                        NUM_D3D11_INIT_ERRORS);
    138        }
    139 #endif
    140 
    141 #if defined(ANGLE_ENABLE_D3D9)
    142        if (renderer->getRendererClass() == RENDERER_D3D9)
    143        {
    144            ASSERT(result.getID() >= 0 && result.getID() < NUM_D3D9_INIT_ERRORS);
    145            ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3D9InitializeResult", result.getID(),
    146                                        NUM_D3D9_INIT_ERRORS);
    147        }
    148 #endif
    149 
    150        if (!result.isError())
    151        {
    152            *outRenderer = renderer;
    153            return result;
    154        }
    155 
    156        // Failed to create the renderer, try the next
    157        SafeDelete(renderer);
    158        ERR() << "Failed to create D3D renderer: " << result.getMessage();
    159    }
    160 
    161    return egl::EglNotInitialized() << "No available renderers.";
    162 }
    163 
    164 DisplayD3D::DisplayD3D(const egl::DisplayState &state) : DisplayImpl(state), mRenderer(nullptr) {}
    165 
    166 SurfaceImpl *DisplayD3D::createWindowSurface(const egl::SurfaceState &state,
    167                                             EGLNativeWindowType window,
    168                                             const egl::AttributeMap &attribs)
    169 {
    170    ASSERT(mRenderer != nullptr);
    171    return new WindowSurfaceD3D(state, mRenderer, mDisplay, window, attribs);
    172 }
    173 
    174 SurfaceImpl *DisplayD3D::createPbufferSurface(const egl::SurfaceState &state,
    175                                              const egl::AttributeMap &attribs)
    176 {
    177    ASSERT(mRenderer != nullptr);
    178    return new PbufferSurfaceD3D(state, mRenderer, mDisplay, 0, nullptr, attribs);
    179 }
    180 
    181 SurfaceImpl *DisplayD3D::createPbufferFromClientBuffer(const egl::SurfaceState &state,
    182                                                       EGLenum buftype,
    183                                                       EGLClientBuffer clientBuffer,
    184                                                       const egl::AttributeMap &attribs)
    185 {
    186    ASSERT(mRenderer != nullptr);
    187    return new PbufferSurfaceD3D(state, mRenderer, mDisplay, buftype, clientBuffer, attribs);
    188 }
    189 
    190 SurfaceImpl *DisplayD3D::createPixmapSurface(const egl::SurfaceState &state,
    191                                             NativePixmapType nativePixmap,
    192                                             const egl::AttributeMap &attribs)
    193 {
    194    UNIMPLEMENTED();
    195    return nullptr;
    196 }
    197 
    198 ImageImpl *DisplayD3D::createImage(const egl::ImageState &state,
    199                                   const gl::Context *context,
    200                                   EGLenum target,
    201                                   const egl::AttributeMap &attribs)
    202 {
    203    return new EGLImageD3D(state, target, attribs, mRenderer);
    204 }
    205 
    206 DeviceImpl *DisplayD3D::createDevice()
    207 {
    208    return mRenderer->createEGLDevice();
    209 }
    210 
    211 rx::ContextImpl *DisplayD3D::createContext(const gl::State &state,
    212                                           gl::ErrorSet *errorSet,
    213                                           const egl::Config *configuration,
    214                                           const gl::Context *shareContext,
    215                                           const egl::AttributeMap &attribs)
    216 {
    217    ASSERT(mRenderer != nullptr);
    218    return mRenderer->createContext(state, errorSet);
    219 }
    220 
    221 StreamProducerImpl *DisplayD3D::createStreamProducerD3DTexture(
    222    egl::Stream::ConsumerType consumerType,
    223    const egl::AttributeMap &attribs)
    224 {
    225    ASSERT(mRenderer != nullptr);
    226    return mRenderer->createStreamProducerD3DTexture(consumerType, attribs);
    227 }
    228 
    229 ExternalImageSiblingImpl *DisplayD3D::createExternalImageSibling(const gl::Context *context,
    230                                                                 EGLenum target,
    231                                                                 EGLClientBuffer buffer,
    232                                                                 const egl::AttributeMap &attribs)
    233 {
    234    ASSERT(mRenderer != nullptr);
    235    return mRenderer->createExternalImageSibling(context, target, buffer, attribs);
    236 }
    237 
    238 ShareGroupImpl *DisplayD3D::createShareGroup()
    239 {
    240    return new ShareGroupD3D();
    241 }
    242 
    243 egl::Error DisplayD3D::makeCurrent(egl::Display *display,
    244                                   egl::Surface *drawSurface,
    245                                   egl::Surface *readSurface,
    246                                   gl::Context *context)
    247 {
    248    // Ensure the appropriate global DebugAnnotator is used
    249    ASSERT(mRenderer != nullptr);
    250    mRenderer->setGlobalDebugAnnotator();
    251 
    252    return egl::NoError();
    253 }
    254 
    255 egl::Error DisplayD3D::initialize(egl::Display *display)
    256 {
    257    ASSERT(mRenderer == nullptr && display != nullptr);
    258    mDisplay = display;
    259    ANGLE_TRY(CreateRendererD3D(display, &mRenderer));
    260    return egl::NoError();
    261 }
    262 
    263 void DisplayD3D::terminate()
    264 {
    265    SafeDelete(mRenderer);
    266 }
    267 
    268 egl::ConfigSet DisplayD3D::generateConfigs()
    269 {
    270    ASSERT(mRenderer != nullptr);
    271    return mRenderer->generateConfigs();
    272 }
    273 
    274 bool DisplayD3D::testDeviceLost()
    275 {
    276    ASSERT(mRenderer != nullptr);
    277    return mRenderer->testDeviceLost();
    278 }
    279 
    280 egl::Error DisplayD3D::restoreLostDevice(const egl::Display *display)
    281 {
    282    // Release surface resources to make the Reset() succeed
    283    for (egl::Surface *surface : mState.surfaceSet)
    284    {
    285        ASSERT(!surface->getBoundTexture());
    286        SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
    287        surfaceD3D->releaseSwapChain();
    288    }
    289 
    290    if (!mRenderer->resetDevice())
    291    {
    292        return egl::EglBadAlloc();
    293    }
    294 
    295    // Restore any surfaces that may have been lost
    296    for (const egl::Surface *surface : mState.surfaceSet)
    297    {
    298        SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
    299 
    300        ANGLE_TRY(surfaceD3D->resetSwapChain(display));
    301    }
    302 
    303    return egl::NoError();
    304 }
    305 
    306 bool DisplayD3D::isValidNativeWindow(EGLNativeWindowType window) const
    307 {
    308    return mRenderer->isValidNativeWindow(window);
    309 }
    310 
    311 egl::Error DisplayD3D::validateClientBuffer(const egl::Config *config,
    312                                            EGLenum buftype,
    313                                            EGLClientBuffer clientBuffer,
    314                                            const egl::AttributeMap &attribs) const
    315 {
    316    switch (buftype)
    317    {
    318        case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
    319            return mRenderer->validateShareHandle(config, static_cast<HANDLE>(clientBuffer),
    320                                                  attribs);
    321 
    322        case EGL_D3D_TEXTURE_ANGLE:
    323            return mRenderer->getD3DTextureInfo(config, static_cast<IUnknown *>(clientBuffer),
    324                                                attribs, nullptr, nullptr, nullptr, nullptr,
    325                                                nullptr, nullptr);
    326 
    327        default:
    328            return DisplayImpl::validateClientBuffer(config, buftype, clientBuffer, attribs);
    329    }
    330 }
    331 
    332 egl::Error DisplayD3D::validateImageClientBuffer(const gl::Context *context,
    333                                                 EGLenum target,
    334                                                 EGLClientBuffer clientBuffer,
    335                                                 const egl::AttributeMap &attribs) const
    336 {
    337    switch (target)
    338    {
    339        case EGL_D3D11_TEXTURE_ANGLE:
    340        {
    341            return mRenderer->getD3DTextureInfo(nullptr, static_cast<IUnknown *>(clientBuffer),
    342                                                attribs, nullptr, nullptr, nullptr, nullptr,
    343                                                nullptr, nullptr);
    344        }
    345 
    346        default:
    347            return DisplayImpl::validateImageClientBuffer(context, target, clientBuffer, attribs);
    348    }
    349 }
    350 
    351 void DisplayD3D::generateExtensions(egl::DisplayExtensions *outExtensions) const
    352 {
    353    mRenderer->generateDisplayExtensions(outExtensions);
    354 }
    355 
    356 std::string DisplayD3D::getRendererDescription()
    357 {
    358    if (mRenderer)
    359    {
    360        return mRenderer->getRendererDescription();
    361    }
    362    return std::string();
    363 }
    364 
    365 std::string DisplayD3D::getVendorString()
    366 {
    367    if (mRenderer)
    368    {
    369        return mRenderer->getVendorString();
    370    }
    371    return std::string();
    372 }
    373 
    374 std::string DisplayD3D::getVersionString(bool includeFullVersion)
    375 {
    376    if (mRenderer)
    377    {
    378        return mRenderer->getVersionString(includeFullVersion);
    379    }
    380    return std::string();
    381 }
    382 
    383 void DisplayD3D::generateCaps(egl::Caps *outCaps) const
    384 {
    385    // Display must be initialized to generate caps
    386    ASSERT(mRenderer != nullptr);
    387 
    388    outCaps->textureNPOT = mRenderer->getNativeExtensions().textureNpotOES;
    389 }
    390 
    391 egl::Error DisplayD3D::waitClient(const gl::Context *context)
    392 {
    393    for (egl::Surface *surface : mState.surfaceSet)
    394    {
    395        SurfaceD3D *surfaceD3D = GetImplAs<SurfaceD3D>(surface);
    396        ANGLE_TRY(surfaceD3D->checkForOutOfDateSwapChain(this));
    397    }
    398 
    399    return egl::NoError();
    400 }
    401 
    402 egl::Error DisplayD3D::waitNative(const gl::Context *context, EGLint engine)
    403 {
    404    egl::Surface *drawSurface = context->getCurrentDrawSurface();
    405    egl::Surface *readSurface = context->getCurrentReadSurface();
    406 
    407    if (drawSurface != nullptr)
    408    {
    409        SurfaceD3D *drawSurfaceD3D = GetImplAs<SurfaceD3D>(drawSurface);
    410        ANGLE_TRY(drawSurfaceD3D->checkForOutOfDateSwapChain(this));
    411    }
    412 
    413    if (readSurface != nullptr)
    414    {
    415        SurfaceD3D *readSurfaceD3D = GetImplAs<SurfaceD3D>(readSurface);
    416        ANGLE_TRY(readSurfaceD3D->checkForOutOfDateSwapChain(this));
    417    }
    418 
    419    return egl::NoError();
    420 }
    421 
    422 gl::Version DisplayD3D::getMaxSupportedESVersion() const
    423 {
    424    return mRenderer->getMaxSupportedESVersion();
    425 }
    426 
    427 gl::Version DisplayD3D::getMaxConformantESVersion() const
    428 {
    429    return mRenderer->getMaxConformantESVersion();
    430 }
    431 
    432 Optional<gl::Version> DisplayD3D::getMaxSupportedDesktopVersion() const
    433 {
    434    return Optional<gl::Version>::Invalid();
    435 }
    436 
    437 void DisplayD3D::handleResult(HRESULT hr,
    438                              const char *message,
    439                              const char *file,
    440                              const char *function,
    441                              unsigned int line)
    442 {
    443    ASSERT(FAILED(hr));
    444 
    445    std::stringstream errorStream;
    446    errorStream << "Internal D3D11 error: " << gl::FmtHR(hr) << ", in " << file << ", " << function
    447                << ":" << line << ". " << message;
    448 
    449    mStoredErrorString = errorStream.str();
    450 }
    451 
    452 void DisplayD3D::initializeFrontendFeatures(angle::FrontendFeatures *features) const
    453 {
    454    mRenderer->initializeFrontendFeatures(features);
    455 }
    456 
    457 void DisplayD3D::populateFeatureList(angle::FeatureList *features)
    458 {
    459    mRenderer->getFeatures().populateFeatureList(features);
    460 }
    461 
    462 }  // namespace rx