Edit

kc3-lang/angle/util/windows/winrt/WinRTWindow.cpp

Branch :

  • Show log

    Commit

  • Author : Jamie Madill
    Date : 2019-01-03 13:01:08
    Hash : ad398ee8
    Message : Free OSWindow and EGLWindow through helpers. This cleans up any potential problems with allocating and freeing resources in different shared objects or DLLs. Previously we were using a dynamically linked allocation function and then calling the standard delete function. Also adds a base class helper for EGLWindow. Will base the WGL Window class on this. Needed for running ANGLE tests against native drivers. Bug: angleproject:2995 Change-Id: Ic92b447649ebb32c547605c20086c07a601842f0 Reviewed-on: https://chromium-review.googlesource.com/c/1393443 Commit-Queue: Jamie Madill <jmadill@chromium.org> Reviewed-by: Yuly Novikov <ynovikov@chromium.org>

  • util/windows/winrt/WinRTWindow.cpp
  • //
    // Copyright (c) 2015 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    // WinRTWindow.cpp: Implementation of OSWindow for WinRT (Windows)
    
    #include "windows/winrt/WinRTWindow.h"
    
    #include <windows.applicationmodel.core.h>
    #include <windows.ui.xaml.h>
    #include <wrl.h>
    
    #include "angle_windowsstore.h"
    #include "common/debug.h"
    
    using namespace ABI::Windows::ApplicationModel::Core;
    using namespace ABI::Windows::Foundation;
    using namespace ABI::Windows::Foundation::Collections;
    using namespace ABI::Windows::UI::Core;
    using namespace Microsoft::WRL;
    using namespace Microsoft::WRL::Wrappers;
    
    WinRTWindow::WinRTWindow() : mNativeWindow(nullptr) {}
    
    WinRTWindow::~WinRTWindow()
    {
        destroy();
    }
    
    bool WinRTWindow::initialize(const std::string &name, size_t width, size_t height)
    {
        ComPtr<ICoreWindowStatic> coreWindowStatic;
        ComPtr<IActivationFactory> propertySetFactory;
        ComPtr<IPropertyValueStatics> propertyValueStatics;
    
        ComPtr<ICoreApplication> coreApplication;
        ComPtr<IPropertySet> coreApplicationProperties;
        ComPtr<IMap<HSTRING, IInspectable *>> coreApplicationPropertiesAsMap;
    
        ComPtr<IMap<HSTRING, IInspectable *>> nativeWindowAsMap;
        ComPtr<IInspectable> sizeValue;
    
        HRESULT result           = S_OK;
        boolean propertyReplaced = false;
    
        destroy();
    
        // Get all the relevant activation factories
        result = GetActivationFactory(HStringReference(RuntimeClass_Windows_UI_Core_CoreWindow).Get(),
                                      &coreWindowStatic);
        if (FAILED(result))
        {
            return false;
        }
    
        result = GetActivationFactory(
            HStringReference(RuntimeClass_Windows_Foundation_Collections_PropertySet).Get(),
            &propertySetFactory);
        if (FAILED(result))
        {
            return false;
        }
    
        result =
            GetActivationFactory(HStringReference(RuntimeClass_Windows_Foundation_PropertyValue).Get(),
                                 &propertyValueStatics);
        if (FAILED(result))
        {
            return false;
        }
    
        result = GetActivationFactory(
            HStringReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
            &coreApplication);
        if (FAILED(result))
        {
            return false;
        }
    
        // Create a PropertySet to be used as the native window
        result = propertySetFactory->ActivateInstance(&mNativeWindow);
        if (FAILED(result))
        {
            return false;
        }
    
        // Get the PropertySet as a map, so we can Insert things into it later
        ComPtr<IInspectable> tempNativeWindow = mNativeWindow;
        result                                = tempNativeWindow.As(&nativeWindowAsMap);
        if (FAILED(result))
        {
            return false;
        }
    
        // Get the CoreApplication properties
        result = coreApplication->get_Properties(coreApplicationProperties.GetAddressOf());
        if (FAILED(result))
        {
            return false;
        }
    
        // Get the CoreApplication properties as a map
        result = coreApplicationProperties.As(&coreApplicationPropertiesAsMap);
        if (FAILED(result))
        {
            return false;
        }
    
        // See if the application properties contain an EGLNativeWindowTypeProperty
        boolean hasEGLNativeWindowTypeProperty;
        result = coreApplicationPropertiesAsMap->HasKey(
            HStringReference(EGLNativeWindowTypeProperty).Get(), &hasEGLNativeWindowTypeProperty);
        if (FAILED(result))
        {
            return false;
        }
    
        // If an EGLNativeWindowTypeProperty is inputted then use it
        if (hasEGLNativeWindowTypeProperty)
        {
            ComPtr<IInspectable> coreApplicationPropertyNativeWindow;
    
            result = coreApplicationPropertiesAsMap->Lookup(
                HStringReference(EGLNativeWindowTypeProperty).Get(),
                &coreApplicationPropertyNativeWindow);
            if (FAILED(result))
            {
                return false;
            }
    
            // See if the inputted window was a CoreWindow
            ComPtr<ICoreWindow> applicationPropertyCoreWindow;
            if (SUCCEEDED(coreApplicationPropertyNativeWindow.As(&applicationPropertyCoreWindow)))
            {
                // Store away the CoreWindow's dispatcher, to be used later to process messages
                result = applicationPropertyCoreWindow->get_Dispatcher(&mCoreDispatcher);
                if (FAILED(result))
                {
                    return false;
                }
            }
            else
            {
                ComPtr<IPropertySet> propSet;
    
                // Disallow Property Sets here, since we want to wrap this window in
                // a property set with the size property below
                if (SUCCEEDED(coreApplicationPropertyNativeWindow.As(&propSet)))
                {
                    return false;
                }
            }
    
            // Add the window to the map
            result =
                nativeWindowAsMap->Insert(HStringReference(EGLNativeWindowTypeProperty).Get(),
                                          coreApplicationPropertyNativeWindow.Get(), &propertyReplaced);
            if (FAILED(result))
            {
                return false;
            }
        }
        else
        {
            ComPtr<ICoreWindow> currentThreadCoreWindow;
    
            // Get the CoreWindow for the current thread
            result = coreWindowStatic->GetForCurrentThread(&currentThreadCoreWindow);
            if (FAILED(result))
            {
                return false;
            }
    
            // By default, just add this thread's CoreWindow to the PropertySet
            result = nativeWindowAsMap->Insert(HStringReference(EGLNativeWindowTypeProperty).Get(),
                                               currentThreadCoreWindow.Get(), &propertyReplaced);
            if (FAILED(result))
            {
                return false;
            }
    
            // Store away the CoreWindow's dispatcher, to be used later to process messages
            result = currentThreadCoreWindow->get_Dispatcher(&mCoreDispatcher);
            if (FAILED(result))
            {
                return false;
            }
        }
    
        // Create a Size to represent the Native Window's size
        Size renderSize;
        renderSize.Width  = static_cast<float>(width);
        renderSize.Height = static_cast<float>(height);
        result            = propertyValueStatics->CreateSize(renderSize, sizeValue.GetAddressOf());
        if (FAILED(result))
        {
            return false;
        }
    
        // Add the Size to the PropertySet
        result = nativeWindowAsMap->Insert(HStringReference(EGLRenderSurfaceSizeProperty).Get(),
                                           sizeValue.Get(), &propertyReplaced);
        if (FAILED(result))
        {
            return false;
        }
    
        return true;
    };
    
    void WinRTWindow::destroy()
    {
        SafeRelease(mNativeWindow);
    
        mCoreDispatcher.Reset();
    }
    
    EGLNativeWindowType WinRTWindow::getNativeWindow() const
    {
        return mNativeWindow;
    }
    
    EGLNativeDisplayType WinRTWindow::getNativeDisplay() const
    {
        UNIMPLEMENTED();
        return static_cast<EGLNativeDisplayType>(0);
    }
    
    void WinRTWindow::messageLoop()
    {
        // If we have a CoreDispatcher then use it to process events
        if (mCoreDispatcher)
        {
            HRESULT result =
                mCoreDispatcher->ProcessEvents(CoreProcessEventsOption_ProcessAllIfPresent);
            UNUSED_ASSERTION_VARIABLE(result);
            ASSERT(SUCCEEDED(result));
        }
    }
    
    void WinRTWindow::setMousePosition(int /* x */, int /* y */)
    {
        UNIMPLEMENTED();
    }
    
    bool WinRTWindow::setPosition(int /* x */, int /* y */)
    {
        UNIMPLEMENTED();
        return false;
    }
    
    bool WinRTWindow::resize(int /* width */, int /* height */)
    {
        UNIMPLEMENTED();
        return false;
    }
    
    void WinRTWindow::setVisible(bool isVisible)
    {
        if (isVisible)
        {
            // Already visible by default
            return;
        }
        else
        {
            // Not implemented in WinRT
            UNIMPLEMENTED();
        }
    }
    
    void WinRTWindow::signalTestEvent()
    {
        UNIMPLEMENTED();
    }
    
    OSWindow *OSWindow::New()
    {
        return new WinRTWindow();
    }