• 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 // 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