xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/wgl/WindowSurfaceWGL.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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         return egl::EglBadNativeWindow()
47                << "Failed to get the device context from the native window, "
48                << gl::FmtErr(GetLastError());
49     }
50 
51     // Require that the pixel format for this window has not been set yet or is equal to the
52     // Display's pixel format.
53     int windowPixelFormat = GetPixelFormat(mDeviceContext);
54     if (windowPixelFormat == 0)
55     {
56         PIXELFORMATDESCRIPTOR pixelFormatDescriptor = {};
57         if (!DescribePixelFormat(mDeviceContext, mPixelFormat, sizeof(pixelFormatDescriptor),
58                                  &pixelFormatDescriptor))
59         {
60             return egl::EglBadNativeWindow()
61                    << "Failed to DescribePixelFormat, " << gl::FmtErr(GetLastError());
62         }
63 
64         if (!SetPixelFormat(mDeviceContext, mPixelFormat, &pixelFormatDescriptor))
65         {
66             return egl::EglNotInitialized()
67                    << "Failed to set the pixel format on the device context, "
68                    << gl::FmtErr(GetLastError());
69         }
70     }
71     else if (windowPixelFormat != mPixelFormat)
72     {
73         return egl::EglNotInitialized()
74                << "Pixel format of the NativeWindow and NativeDisplayType must match.";
75     }
76 
77     // Check for the swap behavior of this pixel format
78     switch (
79         wgl::QueryWGLFormatAttrib(mDeviceContext, mPixelFormat, WGL_SWAP_METHOD_ARB, mFunctionsWGL))
80     {
81         case WGL_SWAP_COPY_ARB:
82             mSwapBehavior = EGL_BUFFER_PRESERVED;
83             break;
84 
85         case WGL_SWAP_EXCHANGE_ARB:
86         case WGL_SWAP_UNDEFINED_ARB:
87         default:
88             mSwapBehavior = EGL_BUFFER_DESTROYED;
89             break;
90     }
91 
92     return egl::NoError();
93 }
94 
makeCurrent(const gl::Context * context)95 egl::Error WindowSurfaceWGL::makeCurrent(const gl::Context *context)
96 {
97     return egl::NoError();
98 }
99 
swap(const gl::Context * context)100 egl::Error WindowSurfaceWGL::swap(const gl::Context *context)
101 {
102     if (!mFunctionsWGL->swapBuffers(mDeviceContext))
103     {
104         // TODO: What error type here?
105         return egl::EglContextLost() << "Failed to swap buffers on the child window.";
106     }
107 
108     return egl::NoError();
109 }
110 
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)111 egl::Error WindowSurfaceWGL::postSubBuffer(const gl::Context *context,
112                                            EGLint x,
113                                            EGLint y,
114                                            EGLint width,
115                                            EGLint height)
116 {
117     UNIMPLEMENTED();
118     return egl::NoError();
119 }
120 
querySurfacePointerANGLE(EGLint attribute,void ** value)121 egl::Error WindowSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
122 {
123     *value = nullptr;
124     return egl::NoError();
125 }
126 
bindTexImage(const gl::Context * context,gl::Texture * texture,EGLint buffer)127 egl::Error WindowSurfaceWGL::bindTexImage(const gl::Context *context,
128                                           gl::Texture *texture,
129                                           EGLint buffer)
130 {
131     UNIMPLEMENTED();
132     return egl::NoError();
133 }
134 
releaseTexImage(const gl::Context * context,EGLint buffer)135 egl::Error WindowSurfaceWGL::releaseTexImage(const gl::Context *context, EGLint buffer)
136 {
137     UNIMPLEMENTED();
138     return egl::NoError();
139 }
140 
setSwapInterval(const egl::Display * display,EGLint interval)141 void WindowSurfaceWGL::setSwapInterval(const egl::Display *display, EGLint interval)
142 {
143     if (mFunctionsWGL->swapIntervalEXT)
144     {
145         mFunctionsWGL->swapIntervalEXT(interval);
146     }
147 }
148 
getWidth() const149 EGLint WindowSurfaceWGL::getWidth() const
150 {
151     RECT rect;
152     if (!GetClientRect(mWindow, &rect))
153     {
154         return 0;
155     }
156     return rect.right - rect.left;
157 }
158 
getHeight() const159 EGLint WindowSurfaceWGL::getHeight() const
160 {
161     RECT rect;
162     if (!GetClientRect(mWindow, &rect))
163     {
164         return 0;
165     }
166     return rect.bottom - rect.top;
167 }
168 
isPostSubBufferSupported() const169 EGLint WindowSurfaceWGL::isPostSubBufferSupported() const
170 {
171     // PostSubBuffer extension not exposed on WGL.
172     UNIMPLEMENTED();
173     return EGL_FALSE;
174 }
175 
getSwapBehavior() const176 EGLint WindowSurfaceWGL::getSwapBehavior() const
177 {
178     return mSwapBehavior;
179 }
180 
getDC() const181 HDC WindowSurfaceWGL::getDC() const
182 {
183     return mDeviceContext;
184 }
185 }  // namespace rx
186