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 return egl::EglBadAlloc() << "Failed to create a native WGL pbuffer, "
99 << gl::FmtErr(HRESULT_CODE(error));
100 }
101
102 // The returned pbuffer may not be as large as requested, update the size members.
103 if (mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_WIDTH_ARB, &mWidth) != TRUE ||
104 mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_HEIGHT_ARB, &mHeight) != TRUE)
105 {
106 DWORD error = GetLastError();
107 return egl::EglBadAlloc() << "Failed to query the WGL pbuffer's dimensions, "
108 << gl::FmtErr(HRESULT_CODE(error));
109 }
110
111 mPbufferDeviceContext = mFunctionsWGL->getPbufferDCARB(mPbuffer);
112 if (mPbufferDeviceContext == nullptr)
113 {
114 mFunctionsWGL->destroyPbufferARB(mPbuffer);
115 mPbuffer = nullptr;
116
117 DWORD error = GetLastError();
118 return egl::EglBadAlloc() << "Failed to get the WGL pbuffer handle, "
119 << gl::FmtErr(HRESULT_CODE(error));
120 }
121
122 return egl::NoError();
123 }
124
makeCurrent(const gl::Context * context)125 egl::Error PbufferSurfaceWGL::makeCurrent(const gl::Context *context)
126 {
127 return egl::NoError();
128 }
129
swap(const gl::Context * context)130 egl::Error PbufferSurfaceWGL::swap(const gl::Context *context)
131 {
132 return egl::NoError();
133 }
134
postSubBuffer(const gl::Context * context,EGLint x,EGLint y,EGLint width,EGLint height)135 egl::Error PbufferSurfaceWGL::postSubBuffer(const gl::Context *context,
136 EGLint x,
137 EGLint y,
138 EGLint width,
139 EGLint height)
140 {
141 return egl::NoError();
142 }
143
querySurfacePointerANGLE(EGLint attribute,void ** value)144 egl::Error PbufferSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value)
145 {
146 *value = nullptr;
147 return egl::NoError();
148 }
149
GetWGLBufferBindTarget(EGLint buffer)150 static int GetWGLBufferBindTarget(EGLint buffer)
151 {
152 switch (buffer)
153 {
154 case EGL_BACK_BUFFER:
155 return WGL_BACK_LEFT_ARB;
156 default:
157 UNREACHABLE();
158 return 0;
159 }
160 }
161
bindTexImage(const gl::Context * context,gl::Texture * texture,EGLint buffer)162 egl::Error PbufferSurfaceWGL::bindTexImage(const gl::Context *context,
163 gl::Texture *texture,
164 EGLint buffer)
165 {
166 if (!mFunctionsWGL->bindTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer)))
167 {
168 DWORD error = GetLastError();
169 return egl::EglBadSurface()
170 << "Failed to bind native wgl pbuffer, " << gl::FmtErr(HRESULT_CODE(error));
171 }
172
173 return egl::NoError();
174 }
175
releaseTexImage(const gl::Context * context,EGLint buffer)176 egl::Error PbufferSurfaceWGL::releaseTexImage(const gl::Context *context, EGLint buffer)
177 {
178 if (!mFunctionsWGL->releaseTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer)))
179 {
180 DWORD error = GetLastError();
181 return egl::EglBadSurface()
182 << "Failed to unbind native wgl pbuffer, " << gl::FmtErr(HRESULT_CODE(error));
183 }
184
185 return egl::NoError();
186 }
187
setSwapInterval(EGLint interval)188 void PbufferSurfaceWGL::setSwapInterval(EGLint interval) {}
189
getWidth() const190 EGLint PbufferSurfaceWGL::getWidth() const
191 {
192 return mWidth;
193 }
194
getHeight() const195 EGLint PbufferSurfaceWGL::getHeight() const
196 {
197 return mHeight;
198 }
199
isPostSubBufferSupported() const200 EGLint PbufferSurfaceWGL::isPostSubBufferSupported() const
201 {
202 return EGL_FALSE;
203 }
204
getSwapBehavior() const205 EGLint PbufferSurfaceWGL::getSwapBehavior() const
206 {
207 return EGL_BUFFER_PRESERVED;
208 }
209
getDC() const210 HDC PbufferSurfaceWGL::getDC() const
211 {
212 return mPbufferDeviceContext;
213 }
214 } // namespace rx
215