summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm')
-rwxr-xr-xgfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm275
1 files changed, 275 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
new file mode 100755
index 000000000..f87134c82
--- /dev/null
+++ b/gfx/angle/src/libANGLE/renderer/gl/cgl/DisplayCGL.mm
@@ -0,0 +1,275 @@
+//
+// 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.
+//
+
+// DisplayCGL.mm: CGL implementation of egl::Display
+
+#include "libANGLE/renderer/gl/cgl/DisplayCGL.h"
+
+#import <Cocoa/Cocoa.h>
+#include <dlfcn.h>
+#include <EGL/eglext.h>
+
+#include "common/debug.h"
+#include "libANGLE/renderer/gl/cgl/PbufferSurfaceCGL.h"
+#include "libANGLE/renderer/gl/cgl/WindowSurfaceCGL.h"
+
+namespace
+{
+
+const char *kDefaultOpenGLDylibName =
+ "/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib";
+const char *kFallbackOpenGLDylibName = "GL";
+
+}
+
+namespace rx
+{
+
+class FunctionsGLCGL : public FunctionsGL
+{
+ public:
+ FunctionsGLCGL(void *dylibHandle) : mDylibHandle(dylibHandle) {}
+
+ ~FunctionsGLCGL() override { dlclose(mDylibHandle); }
+
+ private:
+ void *loadProcAddress(const std::string &function) override
+ {
+ return dlsym(mDylibHandle, function.c_str());
+ }
+
+ void *mDylibHandle;
+};
+
+DisplayCGL::DisplayCGL() : DisplayGL(), mEGLDisplay(nullptr), mFunctions(nullptr), mContext(nullptr)
+{
+}
+
+DisplayCGL::~DisplayCGL()
+{
+}
+
+egl::Error DisplayCGL::initialize(egl::Display *display)
+{
+ mEGLDisplay = display;
+
+ CGLPixelFormatObj pixelFormat;
+ {
+ // TODO(cwallez) investigate which pixel format we want
+ CGLPixelFormatAttribute attribs[] = {
+ kCGLPFAOpenGLProfile, static_cast<CGLPixelFormatAttribute>(kCGLOGLPVersion_3_2_Core),
+ static_cast<CGLPixelFormatAttribute>(0)};
+ GLint nVirtualScreens = 0;
+ CGLChoosePixelFormat(attribs, &pixelFormat, &nVirtualScreens);
+
+ if (pixelFormat == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create the context's pixel format.");
+ }
+ }
+
+ CGLCreateContext(pixelFormat, nullptr, &mContext);
+ if (mContext == nullptr)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not create the CGL context.");
+ }
+ CGLSetCurrentContext(mContext);
+
+ // There is no equivalent getProcAddress in CGL so we open the dylib directly
+ void *handle = dlopen(kDefaultOpenGLDylibName, RTLD_NOW);
+ if (!handle)
+ {
+ handle = dlopen(kFallbackOpenGLDylibName, RTLD_NOW);
+ }
+ if (!handle)
+ {
+ return egl::Error(EGL_NOT_INITIALIZED, "Could not open the OpenGL Framework.");
+ }
+
+ mFunctions = new FunctionsGLCGL(handle);
+ mFunctions->initialize();
+
+ return DisplayGL::initialize(display);
+}
+
+void DisplayCGL::terminate()
+{
+ DisplayGL::terminate();
+
+ if (mContext != nullptr)
+ {
+ CGLSetCurrentContext(nullptr);
+ CGLReleaseContext(mContext);
+ mContext = nullptr;
+ }
+
+ SafeDelete(mFunctions);
+}
+
+SurfaceImpl *DisplayCGL::createWindowSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLNativeWindowType window,
+ const egl::AttributeMap &attribs)
+{
+ return new WindowSurfaceCGL(state, this->getRenderer(), window, mFunctions, mContext);
+}
+
+SurfaceImpl *DisplayCGL::createPbufferSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ const egl::AttributeMap &attribs)
+{
+ EGLint width = static_cast<EGLint>(attribs.get(EGL_WIDTH, 0));
+ EGLint height = static_cast<EGLint>(attribs.get(EGL_HEIGHT, 0));
+ return new PbufferSurfaceCGL(state, this->getRenderer(), width, height, mFunctions);
+}
+
+SurfaceImpl *DisplayCGL::createPbufferFromClientBuffer(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ EGLenum buftype,
+ EGLClientBuffer clientBuffer,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+SurfaceImpl *DisplayCGL::createPixmapSurface(const egl::SurfaceState &state,
+ const egl::Config *configuration,
+ NativePixmapType nativePixmap,
+ const egl::AttributeMap &attribs)
+{
+ UNIMPLEMENTED();
+ return nullptr;
+}
+
+egl::Error DisplayCGL::getDevice(DeviceImpl **device)
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+egl::ConfigSet DisplayCGL::generateConfigs()
+{
+ // TODO(cwallez): generate more config permutations
+ egl::ConfigSet configs;
+
+ const gl::Version &maxVersion = getMaxSupportedESVersion();
+ ASSERT(maxVersion >= gl::Version(2, 0));
+ bool supportsES3 = maxVersion >= gl::Version(3, 0);
+
+ egl::Config config;
+
+ // Native stuff
+ config.nativeVisualID = 0;
+ config.nativeVisualType = 0;
+ config.nativeRenderable = EGL_TRUE;
+
+ // Buffer sizes
+ config.redSize = 8;
+ config.greenSize = 8;
+ config.blueSize = 8;
+ config.alphaSize = 8;
+ config.depthSize = 24;
+ config.stencilSize = 8;
+
+ config.colorBufferType = EGL_RGB_BUFFER;
+ config.luminanceSize = 0;
+ config.alphaMaskSize = 0;
+
+ config.bufferSize = config.redSize + config.greenSize + config.blueSize + config.alphaSize;
+
+ config.transparentType = EGL_NONE;
+
+ // Pbuffer
+ config.maxPBufferWidth = 4096;
+ config.maxPBufferHeight = 4096;
+ config.maxPBufferPixels = 4096 * 4096;
+
+ // Caveat
+ config.configCaveat = EGL_NONE;
+
+ // Misc
+ config.sampleBuffers = 0;
+ config.samples = 0;
+ config.level = 0;
+ config.bindToTextureRGB = EGL_FALSE;
+ config.bindToTextureRGBA = EGL_FALSE;
+
+ config.surfaceType = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
+
+ config.minSwapInterval = 1;
+ config.maxSwapInterval = 1;
+
+ config.renderTargetFormat = GL_RGBA8;
+ config.depthStencilFormat = GL_DEPTH24_STENCIL8;
+
+ config.conformant = EGL_OPENGL_ES2_BIT | (supportsES3 ? EGL_OPENGL_ES3_BIT_KHR : 0);
+ config.renderableType = config.conformant;
+
+ config.matchNativePixmap = EGL_NONE;
+
+ configs.add(config);
+ return configs;
+}
+
+bool DisplayCGL::testDeviceLost()
+{
+ // TODO(cwallez) investigate implementing this
+ return false;
+}
+
+egl::Error DisplayCGL::restoreLostDevice()
+{
+ UNIMPLEMENTED();
+ return egl::Error(EGL_BAD_DISPLAY);
+}
+
+bool DisplayCGL::isValidNativeWindow(EGLNativeWindowType window) const
+{
+ // TODO(cwallez) investigate implementing this
+ return true;
+}
+
+std::string DisplayCGL::getVendorString() const
+{
+ // TODO(cwallez) find a useful vendor string
+ return "";
+}
+
+const FunctionsGL *DisplayCGL::getFunctionsGL() const
+{
+ return mFunctions;
+}
+
+void DisplayCGL::generateExtensions(egl::DisplayExtensions *outExtensions) const
+{
+}
+
+void DisplayCGL::generateCaps(egl::Caps *outCaps) const
+{
+ outCaps->textureNPOT = true;
+}
+
+egl::Error DisplayCGL::waitClient() const
+{
+ // TODO(cwallez) UNIMPLEMENTED()
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayCGL::waitNative(EGLint engine,
+ egl::Surface *drawSurface,
+ egl::Surface *readSurface) const
+{
+ // TODO(cwallez) UNIMPLEMENTED()
+ return egl::Error(EGL_SUCCESS);
+}
+
+egl::Error DisplayCGL::getDriverVersion(std::string *version) const
+{
+ *version = "";
+ return egl::Error(EGL_SUCCESS);
+}
+}