tor-browser

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

CompositorNativeWindow11.cpp (11878B)


      1 //
      2 // Copyright 2018 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 // CompositorNativeWindow11.cpp: Implementation of NativeWindow11 using Windows.UI.Composition APIs
      8 // which work in both Win32 and WinRT contexts.
      9 
     10 #include "libANGLE/renderer/d3d/d3d11/converged/CompositorNativeWindow11.h"
     11 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
     12 
     13 #include "common/debug.h"
     14 
     15 using namespace Microsoft::WRL;
     16 
     17 namespace rx
     18 {
     19 
     20 CompositorNativeWindow11::CompositorNativeWindow11(EGLNativeWindowType window, bool hasAlpha)
     21    : NativeWindow11(window), mHasAlpha(hasAlpha)
     22 {
     23    ABI::Windows::UI::Composition::ISpriteVisual *inspPtr =
     24        reinterpret_cast<ABI::Windows::UI::Composition::ISpriteVisual *>(window);
     25    mHostVisual = Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ISpriteVisual>{inspPtr};
     26 }
     27 
     28 CompositorNativeWindow11::~CompositorNativeWindow11() = default;
     29 
     30 bool CompositorNativeWindow11::initialize()
     31 {
     32    return true;
     33 }
     34 
     35 bool CompositorNativeWindow11::getClientRect(LPRECT rect) const
     36 {
     37    ComPtr<ABI::Windows::UI::Composition::IVisual> visual;
     38    mHostVisual.As(&visual);
     39 
     40    ABI::Windows::Foundation::Numerics::Vector2 size;
     41    HRESULT hr = visual->get_Size(&size);
     42    if (FAILED(hr))
     43    {
     44        return false;
     45    }
     46 
     47    ABI::Windows::Foundation::Numerics::Vector3 offset;
     48    hr = visual->get_Offset(&offset);
     49    if (FAILED(hr))
     50    {
     51        return false;
     52    }
     53 
     54    rect->top    = static_cast<LONG>(offset.Y);
     55    rect->left   = static_cast<LONG>(offset.X);
     56    rect->right  = static_cast<LONG>(offset.X) + static_cast<LONG>(size.X);
     57    rect->bottom = static_cast<LONG>(offset.Y) + static_cast<LONG>(size.Y);
     58 
     59    return true;
     60 }
     61 
     62 bool CompositorNativeWindow11::isIconic() const
     63 {
     64    return false;
     65 }
     66 
     67 HRESULT CompositorNativeWindow11::createSwapChain(ID3D11Device *device,
     68                                                  IDXGIFactory *factory,
     69                                                  DXGI_FORMAT format,
     70                                                  UINT width,
     71                                                  UINT height,
     72                                                  UINT samples,
     73                                                  IDXGISwapChain **swapChain)
     74 {
     75    if (device == nullptr || factory == nullptr || swapChain == nullptr || width == 0 ||
     76        height == 0)
     77    {
     78        return E_INVALIDARG;
     79    }
     80 
     81    HRESULT hr{E_FAIL};
     82 
     83    ComPtr<ABI::Windows::UI::Composition::ICompositionObject> hostVisual;
     84    hr = mHostVisual.As(&hostVisual);
     85    if (FAILED(hr))
     86    {
     87        return hr;
     88    }
     89 
     90    Microsoft::WRL::ComPtr<ABI::Windows::UI::Composition::ICompositor> compositor;
     91    hr = hostVisual->get_Compositor(&compositor);
     92    if (FAILED(hr))
     93    {
     94        return hr;
     95    }
     96 
     97    ComPtr<ABI::Windows::UI::Composition::ICompositorInterop> interop;
     98 
     99    hr = compositor.As(&interop);
    100    if (FAILED(hr))
    101    {
    102        return hr;
    103    }
    104 
    105    ComPtr<IDXGIFactory2> factory2;
    106    factory2.Attach(d3d11::DynamicCastComObject<IDXGIFactory2>(factory));
    107 
    108    DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {};
    109    swapChainDesc.Width                 = width;
    110    swapChainDesc.Height                = height;
    111    swapChainDesc.Format                = format;
    112    swapChainDesc.Stereo                = FALSE;
    113    swapChainDesc.SampleDesc.Count      = 1;
    114    swapChainDesc.SampleDesc.Quality    = 0;
    115    swapChainDesc.BufferUsage =
    116        DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_BACK_BUFFER | DXGI_USAGE_SHADER_INPUT;
    117    swapChainDesc.BufferCount = 2;
    118    swapChainDesc.Scaling     = DXGI_SCALING_STRETCH;
    119    swapChainDesc.SwapEffect  = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
    120    swapChainDesc.AlphaMode   = mHasAlpha ? DXGI_ALPHA_MODE_PREMULTIPLIED : DXGI_ALPHA_MODE_IGNORE;
    121 #ifndef ANGLE_ENABLE_WINDOWS_UWP
    122    swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG::DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
    123 #endif
    124    Microsoft::WRL::ComPtr<IDXGISwapChain1> swapChain1;
    125    hr = factory2->CreateSwapChainForComposition(device, &swapChainDesc, nullptr, &swapChain1);
    126    if (SUCCEEDED(hr))
    127    {
    128        swapChain1.CopyTo(swapChain);
    129    }
    130 
    131    hr = interop->CreateCompositionSurfaceForSwapChain(swapChain1.Get(), &mSurface);
    132    if (FAILED(hr))
    133    {
    134        return hr;
    135    }
    136 
    137    hr = compositor->CreateSurfaceBrushWithSurface(mSurface.Get(), &mSurfaceBrush);
    138    if (FAILED(hr))
    139    {
    140        return hr;
    141    }
    142 
    143    hr = mSurfaceBrush.As(&mCompositionBrush);
    144    if (FAILED(hr))
    145    {
    146        return hr;
    147    }
    148 
    149    hr = mHostVisual->put_Brush(mCompositionBrush.Get());
    150    if (FAILED(hr))
    151    {
    152        return hr;
    153    }
    154 
    155    return hr;
    156 }
    157 
    158 void CompositorNativeWindow11::commitChange()
    159 {
    160    // Windows::UI::Composition uses an implicit commit model hence no action needed here
    161 }
    162 
    163 // static
    164 bool CompositorNativeWindow11::IsValidNativeWindow(EGLNativeWindowType window)
    165 {
    166    return IsSupportedWinRelease() && IsSpriteVisual(window);
    167 }
    168 
    169 // static
    170 bool CompositorNativeWindow11::IsSupportedWinRelease()
    171 {
    172    RoHelper helper;
    173    if (!helper.WinRtAvailable())
    174    {
    175        return false;
    176    }
    177 
    178    return helper.SupportedWindowsRelease();
    179 }
    180 
    181 bool CompositorNativeWindow11::IsSpriteVisual(EGLNativeWindowType window)
    182 {
    183    RoHelper helper;
    184 
    185    ABI::Windows::UI::Composition::ISpriteVisual *inspp =
    186        reinterpret_cast<ABI::Windows::UI::Composition::ISpriteVisual *>(window);
    187    HSTRING className, spriteClassName;
    188    HSTRING_HEADER spriteClassNameHeader;
    189 
    190    auto hr = helper.GetStringReference(RuntimeClass_Windows_UI_Composition_SpriteVisual,
    191                                        &spriteClassName, &spriteClassNameHeader);
    192    if (FAILED(hr))
    193    {
    194        return false;
    195    }
    196 
    197    hr = inspp->GetRuntimeClassName(&className);
    198    if (FAILED(hr))
    199    {
    200        return false;
    201    }
    202 
    203    INT32 result = -1;
    204    hr           = helper.WindowsCompareStringOrdinal(className, spriteClassName, &result);
    205 
    206    helper.WindowsDeleteString(className);
    207 
    208    if (FAILED(hr))
    209    {
    210        return false;
    211    }
    212 
    213    if (result == 0)
    214    {
    215        return true;
    216    }
    217 
    218    return false;
    219 }
    220 
    221 // RoHelperImpl
    222 
    223 template <typename T>
    224 bool AssignProcAddress(HMODULE comBaseModule, const char *name, T *&outProc)
    225 {
    226    outProc = reinterpret_cast<T *>(GetProcAddress(comBaseModule, name));
    227    return *outProc != nullptr;
    228 }
    229 
    230 RoHelper::RoHelper()
    231    : mFpWindowsCreateStringReference(nullptr),
    232      mFpGetActivationFactory(nullptr),
    233      mFpWindowsCompareStringOrdinal(nullptr),
    234      mFpCreateDispatcherQueueController(nullptr),
    235      mFpWindowsDeleteString(nullptr),
    236      mFpRoInitialize(nullptr),
    237      mFpRoUninitialize(nullptr),
    238      mWinRtAvailable(false),
    239      mWinRtInitialized(false),
    240      mComBaseModule(nullptr),
    241      mCoreMessagingModule(nullptr)
    242 {
    243 
    244 #ifdef ANGLE_ENABLE_WINDOWS_UWP
    245    mFpWindowsCreateStringReference    = &::WindowsCreateStringReference;
    246    mFpRoInitialize                    = &::RoInitialize;
    247    mFpRoUninitialize                  = &::RoUninitialize;
    248    mFpWindowsDeleteString             = &::WindowsDeleteString;
    249    mFpGetActivationFactory            = &::RoGetActivationFactory;
    250    mFpWindowsCompareStringOrdinal     = &::WindowsCompareStringOrdinal;
    251    mFpCreateDispatcherQueueController = &::CreateDispatcherQueueController;
    252    mWinRtAvailable                    = true;
    253 #else
    254 
    255    mComBaseModule = LoadLibraryA("ComBase.dll");
    256 
    257    if (mComBaseModule == nullptr)
    258    {
    259        return;
    260    }
    261 
    262    if (!AssignProcAddress(mComBaseModule, "WindowsCreateStringReference",
    263                           mFpWindowsCreateStringReference))
    264    {
    265        return;
    266    }
    267 
    268    if (!AssignProcAddress(mComBaseModule, "RoGetActivationFactory", mFpGetActivationFactory))
    269    {
    270        return;
    271    }
    272 
    273    if (!AssignProcAddress(mComBaseModule, "WindowsCompareStringOrdinal",
    274                           mFpWindowsCompareStringOrdinal))
    275    {
    276        return;
    277    }
    278 
    279    if (!AssignProcAddress(mComBaseModule, "WindowsDeleteString", mFpWindowsDeleteString))
    280    {
    281        return;
    282    }
    283 
    284    if (!AssignProcAddress(mComBaseModule, "RoInitialize", mFpRoInitialize))
    285    {
    286        return;
    287    }
    288 
    289    if (!AssignProcAddress(mComBaseModule, "RoUninitialize", mFpRoUninitialize))
    290    {
    291        return;
    292    }
    293 
    294    mCoreMessagingModule = LoadLibraryA("coremessaging.dll");
    295 
    296    if (mCoreMessagingModule == nullptr)
    297    {
    298        return;
    299    }
    300 
    301    if (!AssignProcAddress(mCoreMessagingModule, "CreateDispatcherQueueController",
    302                           mFpCreateDispatcherQueueController))
    303    {
    304        return;
    305    }
    306 
    307    auto result = RoInitialize(RO_INIT_MULTITHREADED);
    308 
    309    if (SUCCEEDED(result) || result == RPC_E_CHANGED_MODE)
    310    {
    311        mWinRtAvailable = true;
    312 
    313        if (SUCCEEDED(result))
    314        {
    315            mWinRtInitialized = true;
    316        }
    317    }
    318 #endif
    319 }
    320 
    321 RoHelper::~RoHelper()
    322 {
    323 #ifndef ANGLE_ENABLE_WINDOWS_UWP
    324    if (mWinRtInitialized)
    325    {
    326        RoUninitialize();
    327    }
    328 
    329    if (mCoreMessagingModule != nullptr)
    330    {
    331        FreeLibrary(mCoreMessagingModule);
    332        mCoreMessagingModule = nullptr;
    333    }
    334 
    335    if (mComBaseModule != nullptr)
    336    {
    337        FreeLibrary(mComBaseModule);
    338        mComBaseModule = nullptr;
    339    }
    340 #endif
    341 }
    342 
    343 bool RoHelper::WinRtAvailable() const
    344 {
    345    return mWinRtAvailable;
    346 }
    347 
    348 bool RoHelper::SupportedWindowsRelease()
    349 {
    350    if (!mWinRtAvailable)
    351    {
    352        return false;
    353    }
    354 
    355    HSTRING className, contractName;
    356    HSTRING_HEADER classNameHeader, contractNameHeader;
    357    boolean isSupported = false;
    358 
    359    HRESULT hr = GetStringReference(RuntimeClass_Windows_Foundation_Metadata_ApiInformation,
    360                                    &className, &classNameHeader);
    361 
    362    if (FAILED(hr))
    363    {
    364        return !!isSupported;
    365    }
    366 
    367    Microsoft::WRL::ComPtr<ABI::Windows::Foundation::Metadata::IApiInformationStatics> api;
    368 
    369    hr = GetActivationFactory(
    370        className, __uuidof(ABI::Windows::Foundation::Metadata::IApiInformationStatics), &api);
    371 
    372    if (FAILED(hr))
    373    {
    374        return !!isSupported;
    375    }
    376 
    377    hr = GetStringReference(L"Windows.Foundation.UniversalApiContract", &contractName,
    378                            &contractNameHeader);
    379    if (FAILED(hr))
    380    {
    381        return !!isSupported;
    382    }
    383 
    384    api->IsApiContractPresentByMajor(contractName, 6, &isSupported);
    385 
    386    return !!isSupported;
    387 }
    388 
    389 HRESULT RoHelper::GetStringReference(PCWSTR source, HSTRING *act, HSTRING_HEADER *header)
    390 {
    391    if (!mWinRtAvailable)
    392    {
    393        return E_FAIL;
    394    }
    395 
    396    const wchar_t *str = static_cast<const wchar_t *>(source);
    397 
    398    unsigned int length;
    399    HRESULT hr = SizeTToUInt32(::wcslen(str), &length);
    400    if (FAILED(hr))
    401    {
    402        return hr;
    403    }
    404 
    405    return mFpWindowsCreateStringReference(source, length, header, act);
    406 }
    407 
    408 HRESULT RoHelper::GetActivationFactory(const HSTRING act, const IID &interfaceId, void **fac)
    409 {
    410    if (!mWinRtAvailable)
    411    {
    412        return E_FAIL;
    413    }
    414    auto hr = mFpGetActivationFactory(act, interfaceId, fac);
    415    return hr;
    416 }
    417 
    418 HRESULT RoHelper::WindowsCompareStringOrdinal(HSTRING one, HSTRING two, int *result)
    419 {
    420    if (!mWinRtAvailable)
    421    {
    422        return E_FAIL;
    423    }
    424    return mFpWindowsCompareStringOrdinal(one, two, result);
    425 }
    426 
    427 HRESULT RoHelper::CreateDispatcherQueueController(
    428    DispatcherQueueOptions options,
    429    ABI::Windows::System::IDispatcherQueueController **dispatcherQueueController)
    430 {
    431    if (!mWinRtAvailable)
    432    {
    433        return E_FAIL;
    434    }
    435    return mFpCreateDispatcherQueueController(options, dispatcherQueueController);
    436 }
    437 
    438 HRESULT RoHelper::WindowsDeleteString(HSTRING one)
    439 {
    440    if (!mWinRtAvailable)
    441    {
    442        return E_FAIL;
    443    }
    444    return mFpWindowsDeleteString(one);
    445 }
    446 
    447 HRESULT RoHelper::RoInitialize(RO_INIT_TYPE type)
    448 {
    449    return mFpRoInitialize(type);
    450 }
    451 
    452 void RoHelper::RoUninitialize()
    453 {
    454    mFpRoUninitialize();
    455 }
    456 
    457 }  // namespace rx