diff options
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp')
-rwxr-xr-x | gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp b/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp new file mode 100755 index 000000000..f2c503616 --- /dev/null +++ b/gfx/angle/src/libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.cpp @@ -0,0 +1,196 @@ +// +// Copyright (c) 2015 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// SurfaceWGL.cpp: WGL implementation of egl::Surface + +#include "libANGLE/renderer/gl/wgl/PbufferSurfaceWGL.h" + +#include "common/debug.h" +#include "libANGLE/renderer/gl/RendererGL.h" +#include "libANGLE/renderer/gl/wgl/FunctionsWGL.h" +#include "libANGLE/renderer/gl/wgl/wgl_utils.h" + +namespace rx +{ + +PbufferSurfaceWGL::PbufferSurfaceWGL(const egl::SurfaceState &state, + RendererGL *renderer, + EGLint width, + EGLint height, + EGLenum textureFormat, + EGLenum textureTarget, + bool largest, + int pixelFormat, + HDC deviceContext, + HGLRC wglContext, + const FunctionsWGL *functions) + : SurfaceGL(state, renderer), + mWidth(width), + mHeight(height), + mLargest(largest), + mTextureFormat(textureFormat), + mTextureTarget(textureTarget), + mPixelFormat(pixelFormat), + mShareWGLContext(wglContext), + mParentDeviceContext(deviceContext), + mPbuffer(nullptr), + mPbufferDeviceContext(nullptr), + mFunctionsWGL(functions) +{ +} + +PbufferSurfaceWGL::~PbufferSurfaceWGL() +{ + mFunctionsWGL->releasePbufferDCARB(mPbuffer, mPbufferDeviceContext); + mPbufferDeviceContext = nullptr; + + mFunctionsWGL->destroyPbufferARB(mPbuffer); + mPbuffer = nullptr; +} + +static int GetWGLTextureType(EGLenum eglTextureType) +{ + switch (eglTextureType) + { + case EGL_NO_TEXTURE: return WGL_NO_TEXTURE_ARB; + case EGL_TEXTURE_RGB: return WGL_TEXTURE_RGB_ARB; + case EGL_TEXTURE_RGBA: return WGL_TEXTURE_RGBA_ARB; + default: UNREACHABLE(); return 0; + } +} + +static int GetWGLTextureTarget(EGLenum eglTextureTarget) +{ + switch (eglTextureTarget) + { + case EGL_NO_TEXTURE: return WGL_NO_TEXTURE_ARB; + case EGL_TEXTURE_2D: return WGL_TEXTURE_2D_ARB; + default: UNREACHABLE(); return 0; + } +} + +egl::Error PbufferSurfaceWGL::initialize() +{ + const int pbufferCreationAttributes[] = + { + WGL_PBUFFER_LARGEST_ARB, mLargest ? 1 : 0, + WGL_TEXTURE_FORMAT_ARB, GetWGLTextureType(mTextureFormat), + WGL_TEXTURE_TARGET_ARB, GetWGLTextureTarget(mTextureTarget), + 0, 0, + }; + + mPbuffer = mFunctionsWGL->createPbufferARB(mParentDeviceContext, mPixelFormat, mWidth, mHeight, + pbufferCreationAttributes); + if (mPbuffer == nullptr) + { + DWORD error = GetLastError(); + return egl::Error(EGL_BAD_ALLOC, "Failed to create a native WGL pbuffer, error: 0x%08x.", HRESULT_CODE(error)); + } + + // The returned pbuffer may not be as large as requested, update the size members. + if (mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_WIDTH_ARB, &mWidth) != TRUE || + mFunctionsWGL->queryPbufferARB(mPbuffer, WGL_PBUFFER_HEIGHT_ARB, &mHeight) != TRUE) + { + DWORD error = GetLastError(); + return egl::Error(EGL_BAD_ALLOC, "Failed to query the WGL pbuffer's dimensions, error: 0x%08x.", HRESULT_CODE(error)); + } + + mPbufferDeviceContext = mFunctionsWGL->getPbufferDCARB(mPbuffer); + if (mPbufferDeviceContext == nullptr) + { + mFunctionsWGL->destroyPbufferARB(mPbuffer); + mPbuffer = nullptr; + + DWORD error = GetLastError(); + return egl::Error(EGL_BAD_ALLOC, "Failed to get the WGL pbuffer handle, error: 0x%08x.", HRESULT_CODE(error)); + } + + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceWGL::makeCurrent() +{ + if (!mFunctionsWGL->makeCurrent(mPbufferDeviceContext, mShareWGLContext)) + { + // TODO: What error type here? + return egl::Error(EGL_CONTEXT_LOST, "Failed to make the WGL context current."); + } + + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceWGL::swap() +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceWGL::postSubBuffer(EGLint x, EGLint y, EGLint width, EGLint height) +{ + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceWGL::querySurfacePointerANGLE(EGLint attribute, void **value) +{ + UNIMPLEMENTED(); + return egl::Error(EGL_SUCCESS); +} + +static int GetWGLBufferBindTarget(EGLint buffer) +{ + switch (buffer) + { + case EGL_BACK_BUFFER: return WGL_BACK_LEFT_ARB; + default: UNREACHABLE(); return 0; + } +} + +egl::Error PbufferSurfaceWGL::bindTexImage(gl::Texture *texture, EGLint buffer) +{ + if (!mFunctionsWGL->bindTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer))) + { + DWORD error = GetLastError(); + return egl::Error(EGL_BAD_SURFACE, "Failed to bind native wgl pbuffer, error: 0x%08x.", HRESULT_CODE(error)); + } + + return egl::Error(EGL_SUCCESS); +} + +egl::Error PbufferSurfaceWGL::releaseTexImage(EGLint buffer) +{ + if (!mFunctionsWGL->releaseTexImageARB(mPbuffer, GetWGLBufferBindTarget(buffer))) + { + DWORD error = GetLastError(); + return egl::Error(EGL_BAD_SURFACE, "Failed to unbind native wgl pbuffer, error: 0x%08x.", HRESULT_CODE(error)); + } + + return egl::Error(EGL_SUCCESS); +} + +void PbufferSurfaceWGL::setSwapInterval(EGLint interval) +{ +} + +EGLint PbufferSurfaceWGL::getWidth() const +{ + return mWidth; +} + +EGLint PbufferSurfaceWGL::getHeight() const +{ + return mHeight; +} + +EGLint PbufferSurfaceWGL::isPostSubBufferSupported() const +{ + return EGL_FALSE; +} + +EGLint PbufferSurfaceWGL::getSwapBehavior() const +{ + return EGL_BUFFER_PRESERVED; +} + +} |