summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h
blob: 2d58f1c00adc42e072f1b42bb32cf3771324d8a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//
// Copyright (c) 2014 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.
//

// InspectableNativeWindow.h: Host specific implementation interface for
// managing IInspectable native window types.

#ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
#define LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_

#include "libANGLE/renderer/d3d/d3d11/NativeWindow.h"

#include "common/platform.h"

#include "angle_windowsstore.h"

#include <windows.ui.xaml.h>
#include <windows.ui.xaml.media.dxinterop.h>

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;

namespace rx
{
long ConvertDipsToPixels(float dips);

class InspectableNativeWindow
{
  public:
    InspectableNativeWindow() :
        mSupportsSwapChainResize(true),
        mSwapChainSizeSpecified(false),
        mSwapChainScaleSpecified(false),
        mSwapChainScale(1.0f),
        mClientRectChanged(false),
        mClientRect({0,0,0,0}),
        mNewClientRect({0,0,0,0}),
        mRotationFlags(NativeWindow::RotateNone)
    {
        mSizeChangedEventToken.value = 0;
    }
    virtual ~InspectableNativeWindow(){}

    virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
    virtual HRESULT createSwapChain(ID3D11Device *device,
                                    DXGIFactory *factory,
                                    DXGI_FORMAT format,
                                    unsigned int width,
                                    unsigned int height,
                                    bool containsAlpha,
                                    DXGISwapChain **swapChain) = 0;

    bool getClientRect(RECT *rect)
    {
        if (mClientRectChanged)
        {
            mClientRect = mNewClientRect;
        }

        *rect = mClientRect;

        return true;
    }

    // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of ANGLE.
    void setNewClientSize(const Size &newWindowSize)
    {
        // If the client doesn't support swapchain resizing then we should have already unregistered from size change handler
        ASSERT(mSupportsSwapChainResize);

        if (mSupportsSwapChainResize)
        {
            // If the swapchain size was specified then we should ignore this call too
            if (!mSwapChainSizeSpecified)
            {
                // We don't have to check if a swapchain scale was specified here; the default value is 1.0f which will have no effect.
                mNewClientRect = { 0, 0, ConvertDipsToPixels(newWindowSize.Width), ConvertDipsToPixels(newWindowSize.Height) };
                mClientRectChanged = true;

                // If a scale was specified, then now is the time to apply the scale matrix for the new swapchain size and window size
                if (mSwapChainScaleSpecified)
                {
                    scaleSwapChain(newWindowSize, mNewClientRect);
                }
            }

            // Even if the swapchain size was fixed, the window might have changed size.
            // In this case, we should recalculate the scale matrix to account for the new window size
            if (mSwapChainSizeSpecified)
            {
                scaleSwapChain(newWindowSize, mClientRect);
            }
        }
    }

    NativeWindow::RotationFlags rotationFlags() const
    {
        return mRotationFlags;
    }

    void setRotationFlags(NativeWindow::RotationFlags flags)
    {
        mRotationFlags = flags;
    }

  protected:
    virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0;

    bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method
    bool mSwapChainSizeSpecified;  // If an EGLRenderSurfaceSizeProperty was specified
    bool mSwapChainScaleSpecified; // If an EGLRenderResolutionScaleProperty was specified
    float mSwapChainScale;         // The scale value specified by the EGLRenderResolutionScaleProperty property
    RECT mClientRect;
    RECT mNewClientRect;
    bool mClientRectChanged;
    NativeWindow::RotationFlags mRotationFlags;

    EventRegistrationToken mSizeChangedEventToken;
};

bool IsValidEGLNativeWindowType(EGLNativeWindowType window);
bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr);
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);

HRESULT GetOptionalPropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
                                 const wchar_t *propertyName,
                                 boolean *hasKey,
                                 ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue);

HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
                                     const wchar_t *propertyName, SIZE *value, bool *valueExists);

HRESULT GetOptionalSinglePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
                                       const wchar_t *propertyName, float *value, bool *valueExists);
}

#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_