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 // SurfaceWGL.cpp: WGL implementation of egl::Surface
8
9 #include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.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
PbufferSurfaceWGL(const egl::SurfaceState & state,EGLint width,EGLint height,EGLenum textureFormat,EGLenum textureTarget,bool largest,int pixelFormat,HDC deviceContext,const FunctionsWGL * functions)19 PbufferSurfaceWGL::PbufferSurfaceWGL(const egl::SurfaceState &state,
20 EGLint width,
21 EGLint height,
22 EGLenum textureFormat,
23 EGLenum textureTarget,
24 bool largest,
25 int pixelFormat,
26 HDC deviceContext,
27 const FunctionsWGL *functions)
28 : SurfaceWGL(state),
29 mWidth(width),
30 mHeight(height),
31 mLargest(largest),
32 mTextureFormat(textureFormat),
33 mTextureTarget(textureTarget),
34 mPixelFormat(pixelFormat),
35 mParentDeviceContext(deviceContext),
36 mPbuffer(nullptr),
37 mPbufferDeviceContext(nullptr),
38 mFunctionsWGL(functions)
39 {}
40
~PbufferSurfaceWGL()41 PbufferSurfaceWGL::~PbufferSurfaceWGL()
42 {
43 mFunctionsWGL->releasePbufferDCARB(mPbuffer, mPbufferDeviceContext);
44 mPbufferDeviceContext = nullptr;
45
46 mFunctionsWGL->destroyPbufferARB(mPbuffer);
47 mPbuffer = nullptr;
48 }
49
GetWGLTextureType(EGLenum eglTextureType)50 static int GetWGLTextureType(EGLenum eglTextureType)
51 {
52 switch (eglTextureType)
53 {
54 case EGL_NO_TEXTURE:
55 return WGL_NO_TEXTURE_ARB;
56 case EGL_TEXTURE_RGB:
57 return WGL_TEXTURE_RGB_ARB;
58 case EGL_TEXTURE_RGBA:
59 return WGL_TEXTURE_RGBA_ARB;
60 default:
61 UNREACHABLE();
62 return 0;
63 }
64 }
65
GetWGLTextureTarget(EGLenum eglTextureTarget)66 static int GetWGLTextureTarget(EGLenum eglTextureTarget)
67 {
68 switch (eglTextureTarget)
69 {
70 case EGL_NO_TEXTURE:
71 return WGL_NO_TEXTURE_ARB;
72 case EGL_TEXTURE_2D:
73 return WGL_TEXTURE_2D_ARB;
74 default:
75 UNREACHABLE();
76 return 0;
77 }
78 }
79
initialize(const egl::Display * display)80 egl::Error PbufferSurfaceWGL::initialize(const egl::Display *display)
81 {
82 const int pbufferCreationAttributes[] = {
83 WGL_PBUFFER_LARGEST_ARB,
84 mLargest ? 1 : 0,
85 WGL_TEXTURE_FORMAT_ARB,
86 GetWGLTextureType(mTextureFormat),
87 WGL_TEXTURE_TARGET_ARB,
88 GetWGLTextureTarget(mTextureTarget),
89 0,
90 0,
91 };
92
93 mPbuffer = mFunctionsWGL->createPbufferARB(mParentDeviceContext, mPixelFormat, mWidth, mHeight,
94 pbufferCreationAttributes);
95 if (mPbuffer == nullptr)
96 {
97 DWORD error = GetLastError();
98 std::ostringstream err;
99 err << "Failed to create a native WGL pbuffer, " << gl::FmtErr(HRESULT_CODE(error));
100 return egl::Error(EGL_BAD_ALLOC, err.str());
101 }
102
103 // The returned pbuffer may not be as large as requested, update the size members.
104 if (mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_WIDTH_ARB, &mWidth) != TRUE ||
105 mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_HEIGHT_ARB, &mHeight) != TRUE)
106 {
107 DWORD error = GetLastError();
108 std::ostringstream err;
109 err << "Failed to query the WGL pbuffer's dimensions, " << gl::FmtErr(HRESULT_CODE(error));
110 return egl::Error(EGL_BAD_ALLOC, err.str());
111 }
112
113 mPbufferDeviceContext = mFunctionsWGL->getPbufferDCARB(mPbuffer);
114 if (mPbufferDeviceContext == nullptr)
115 {
116 mFunctionsWGL->destroyPbufferARB(mPbuffer);
117 mPbuffer = nullptr;
118
119 DWORD error = GetLastError();
120 std::ostringstream err;
121 err << "Failed to get the WGL pbuffer handle, " << gl::FmtErr(HRESULT_CODE(error));
122 return egl::Error(EGL_BAD_ALLOC, err.str());
123 }
124
125 return egl::NoError();
126 }
127
makeCurrent(const gl::Context * context)128 egl::Error PbufferSurfaceWGL::makeCurrent(const gl::Context *context)
129 {
130 return egl::NoError();
131 }
132
swap(const gl::Context * context,SurfaceSwapFeedback * feedback)133 egl::Error PbufferSurfaceWGL::swap(const gl::Context *context, SurfaceSwapFeedback *feedback)
134 {
135 return egl::NoError();
136 }
137
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)138 egl::Error PbufferSurfaceWGL::postSubBuffer(const gl::Context *context,
139 EGLint x,
140 EGLint y,
141 EGLint width,
142 EGLint height)
143 {
144 return egl::NoError();
145 }
146
querySurfacePointerANGLE(EGLint attribute,void ** value)147 egl::Error PbufferSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
148 {
149 *value = nullptr;
150 return egl::NoError();
151 }
152
GetWGLBufferBindTarget(EGLint buffer)153 static int GetWGLBufferBindTarget(EGLint buffer)
154 {
155 switch (buffer)
156 {
157 case EGL_BACK_BUFFER:
158 return WGL_BACK_LEFT_ARB;
159 default:
160 UNREACHABLE();
161 return 0;
162 }
163 }
164
bindTexImage(const gl::Context * context,gl::Texture * texture,EGLint buffer)165 egl::Error PbufferSurfaceWGL::bindTexImage(const gl::Context *context,
166 gl::Texture *texture,
167 EGLint buffer)
168 {
169 if (!mFunctionsWGL->bindTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer)))
170 {
171 DWORD error = GetLastError();
172 std::ostringstream err;
173 err << "Failed to bind native wgl pbuffer, " << gl::FmtErr(HRESULT_CODE(error));
174 return egl::Error(EGL_BAD_SURFACE, err.str());
175 }
176
177 return egl::NoError();
178 }
179
releaseTexImage(const gl::Context * context,EGLint buffer)180 egl::Error PbufferSurfaceWGL::releaseTexImage(const gl::Context *context, EGLint buffer)
181 {
182 if (!mFunctionsWGL->releaseTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer)))
183 {
184 DWORD error = GetLastError();
185 std::ostringstream err;
186 err << "Failed to unbind native wgl pbuffer, " << gl::FmtErr(HRESULT_CODE(error));
187 return egl::Error(EGL_BAD_SURFACE, err.str());
188 }
189
190 return egl::NoError();
191 }
192
setSwapInterval(const egl::Display * display,EGLint interval)193 void PbufferSurfaceWGL::setSwapInterval(const egl::Display *display, EGLint interval) {}
194
getWidth() const195 EGLint PbufferSurfaceWGL::getWidth() const
196 {
197 return mWidth;
198 }
199
getHeight() const200 EGLint PbufferSurfaceWGL::getHeight() const
201 {
202 return mHeight;
203 }
204
isPostSubBufferSupported() const205 EGLint PbufferSurfaceWGL::isPostSubBufferSupported() const
206 {
207 return EGL_FALSE;
208 }
209
getSwapBehavior() const210 EGLint PbufferSurfaceWGL::getSwapBehavior() const
211 {
212 return EGL_BUFFER_PRESERVED;
213 }
214
getDC() const215 HDC PbufferSurfaceWGL::getDC() const
216 {
217 return mPbufferDeviceContext;
218 }
219 } // namespace rx
220