• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 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 // WindowSurfaceWGL.cpp: WGL implementation of egl::Surface for windows
8 
9 #include "libANGLE/renderer/gl/wgl/WindowSurfaceWGL.h"
10 
11 #include "common/debug.h"
12 #include "libANGLE/renderer/gl/RendererGL.h"
13 #include "libANGLE/renderer/gl/wgl/FunctionsWGL.h"
14 #include "libANGLE/renderer/gl/wgl/wgl_utils.h"
15 
16 namespace rx
17 {
18 
WindowSurfaceWGL(const egl::SurfaceState & state,EGLNativeWindowType window,int pixelFormat,const FunctionsWGL * functions,EGLint orientation)19 WindowSurfaceWGL::WindowSurfaceWGL(const egl::SurfaceState &state,
20                                    EGLNativeWindowType window,
21                                    int pixelFormat,
22                                    const FunctionsWGL *functions,
23                                    EGLint orientation)
24     : SurfaceWGL(state),
25       mPixelFormat(pixelFormat),
26       mWindow(window),
27       mDeviceContext(nullptr),
28       mFunctionsWGL(functions),
29       mSwapBehavior(0)
30 {
31     // EGL_ANGLE_surface_orientation is not supported for regular WGL window surfaces
32     ASSERT(orientation == 0);
33 }
34 
~WindowSurfaceWGL()35 WindowSurfaceWGL::~WindowSurfaceWGL()
36 {
37     ReleaseDC(mWindow, mDeviceContext);
38     mDeviceContext = nullptr;
39 }
40 
initialize(const egl::Display * display)41 egl::Error WindowSurfaceWGL::initialize(const egl::Display *display)
42 {
43     mDeviceContext = GetDC(mWindow);
44     if (!mDeviceContext)
45     {
46         std::ostringstream err;
47         err << "Failed to get the device context from the native window, "
48             << gl::FmtErr(GetLastError());
49         return egl::Error(EGL_BAD_NATIVE_WINDOW, err.str());
50     }
51 
52     // Require that the pixel format for this window has not been set yet or is equal to the
53     // Display's pixel format.
54     int windowPixelFormat = GetPixelFormat(mDeviceContext);
55     if (windowPixelFormat == 0)
56     {
57         PIXELFORMATDESCRIPTOR pixelFormatDescriptor = {};
58         if (!DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor),
59                                  &pixelFormatDescriptor))
60         {
61             std::ostringstream err;
62             err << "Failed to DescribePixelFormat, " << gl::FmtErr(GetLastError());
63             return egl::Error(EGL_BAD_NATIVE_WINDOW, err.str());
64         }
65 
66         if (!SetPixelFormat(mDeviceContext, mPixelFormat, &pixelFormatDescriptor))
67         {
68             std::ostringstream err;
69             err << "Failed to set the pixel format on the device context, "
70                 << gl::FmtErr(GetLastError());
71             return egl::Error(EGL_NOT_INITIALIZED, err.str());
72         }
73     }
74     else if (windowPixelFormat != mPixelFormat)
75     {
76         return egl::Error(EGL_NOT_INITIALIZED,
77                           "Pixel format of the NativeWindow and NativeDisplayType must match.");
78     }
79 
80     // Check for the swap behavior of this pixel format
81     switch (
82         wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_SWAP_METHOD_ARB, mFunctionsWGL))
83     {
84         case WGL_SWAP_COPY_ARB:
85             mSwapBehavior = EGL_BUFFER_PRESERVED;
86             break;
87 
88         case WGL_SWAP_EXCHANGE_ARB:
89         case WGL_SWAP_UNDEFINED_ARB:
90         default:
91             mSwapBehavior = EGL_BUFFER_DESTROYED;
92             break;
93     }
94 
95     return egl::NoError();
96 }
97 
makeCurrent(const gl::Context * context)98 egl::Error WindowSurfaceWGL::makeCurrent(const gl::Context *context)
99 {
100     return egl::NoError();
101 }
102 
swap(const gl::Context * context,SurfaceSwapFeedback * feedback)103 egl::Error WindowSurfaceWGL::swap(const gl::Context *context, SurfaceSwapFeedback *feedback)
104 {
105     if (!mFunctionsWGL->swapBuffers(mDeviceContext))
106     {
107         // TODO: What error type here?
108         return egl::Error(EGL_CONTEXT_LOST, "Failed to swap buffers on the child window.");
109     }
110 
111     return egl::NoError();
112 }
113 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)114 egl::Error WindowSurfaceWGL::postSubBuffer(const gl::Context *context,
115                                            EGLint x,
116                                            EGLint y,
117                                            EGLint width,
118                                            EGLint height)
119 {
120     UNIMPLEMENTED();
121     return egl::NoError();
122 }
123 
querySurfacePointerANGLE(EGLint attribute,void ** value)124 egl::Error WindowSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
125 {
126     *value = nullptr;
127     return egl::NoError();
128 }
129 
bindTexImage(const gl::Context * context,gl::Texture * texture,EGLint buffer)130 egl::Error WindowSurfaceWGL::bindTexImage(const gl::Context *context,
131                                           gl::Texture *texture,
132                                           EGLint buffer)
133 {
134     UNIMPLEMENTED();
135     return egl::NoError();
136 }
137 
releaseTexImage(const gl::Context * context,EGLint buffer)138 egl::Error WindowSurfaceWGL::releaseTexImage(const gl::Context *context, EGLint buffer)
139 {
140     UNIMPLEMENTED();
141     return egl::NoError();
142 }
143 
setSwapInterval(const egl::Display * display,EGLint interval)144 void WindowSurfaceWGL::setSwapInterval(const egl::Display *display, EGLint interval)
145 {
146     if (mFunctionsWGL->swapIntervalEXT)
147     {
148         mFunctionsWGL->swapIntervalEXT(interval);
149     }
150 }
151 
getWidth() const152 EGLint WindowSurfaceWGL::getWidth() const
153 {
154     RECT rect;
155     if (!GetClientRect(mWindow, &rect))
156     {
157         return 0;
158     }
159     return rect.right - rect.left;
160 }
161 
getHeight() const162 EGLint WindowSurfaceWGL::getHeight() const
163 {
164     RECT rect;
165     if (!GetClientRect(mWindow, &rect))
166     {
167         return 0;
168     }
169     return rect.bottom - rect.top;
170 }
171 
isPostSubBufferSupported() const172 EGLint WindowSurfaceWGL::isPostSubBufferSupported() const
173 {
174     // PostSubBuffer extension not exposed on WGL.
175     UNIMPLEMENTED();
176     return EGL_FALSE;
177 }
178 
getSwapBehavior() const179 EGLint WindowSurfaceWGL::getSwapBehavior() const
180 {
181     return mSwapBehavior;
182 }
183 
getDC() const184 HDC WindowSurfaceWGL::getDC() const
185 {
186     return mDeviceContext;
187 }
188 }  // namespace rx
189