13724e574a744491b7cfb8187ac865a70ef3d4528bsalomon
2373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com/*
3373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com * Copyright 2011 Google Inc.
4373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com *
5373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
6373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com * found in the LICENSE file.
7373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com */
81ee76510f5dbf632d30975fc3509ef4f609156d2mtklein#include "SkTypes.h"
91ee76510f5dbf632d30975fc3509ef4f609156d2mtklein
10273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon#include "gl/GLTestContext.h"
116918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com#include "AvailabilityMacros.h"
12373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
139e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen#include <OpenGL/OpenGL.h>
14d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton#include <dlfcn.h>
15a90ed4e83897b45d6331ee4c54e1edd4054de9a8kkinnunen
169e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunennamespace {
17273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonclass MacGLTestContext : public sk_gpu_test::GLTestContext {
189e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunenpublic:
1960c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    MacGLTestContext(MacGLTestContext* shareContext);
20273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon    ~MacGLTestContext() override;
2157f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com
229e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunenprivate:
2330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    void destroyGLContext();
2430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
25d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    void onPlatformMakeCurrent() const override;
26d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    void onPlatformSwapBuffers() const override;
27d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
28d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton
299e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen    CGLContextObj fContext;
30d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    void* fGLLibrary;
319e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen};
3257f5d9854bfc78c347cb587e044fb3950f9ad298bsalomon@google.com
3360c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian OsmanMacGLTestContext::MacGLTestContext(MacGLTestContext* shareContext)
3496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    : fContext(nullptr)
35d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    , fGLLibrary(RTLD_DEFAULT) {
36682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com    CGLPixelFormatAttribute attributes[] = {
376918d482d64f045a4c980b2fb267bc939953638ebsalomon@google.com#if MAC_OS_X_VERSION_10_7
381744f97ea73384b9f75b0ccee0a36a213c681d3absalomon@google.com        kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute) kCGLOGLPVersion_3_2_Core,
39682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com#endif
40c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com        kCGLPFADoubleBuffer,
41682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com        (CGLPixelFormatAttribute)0
42373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    };
43682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com    CGLPixelFormatObj pixFormat;
44682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com    GLint npix;
45044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com
46682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com    CGLChoosePixelFormat(attributes, &pixFormat, &npix);
47044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com
4896fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == pixFormat) {
49682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com        SkDebugf("CGLChoosePixelFormat failed.");
5030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
51373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
52044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com
5360c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    CGLCreateContext(pixFormat, shareContext ? shareContext->fContext : nullptr, &fContext);
54682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com    CGLReleasePixelFormat(pixFormat);
55044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com
5696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == fContext) {
57682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com        SkDebugf("CGLCreateContext failed.");
5830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
59373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
60044679ef8c08e1f01afadf5bc08251fe8597df81skia.committer@gmail.com
61682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com    CGLSetCurrentContext(fContext);
62fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
631b612a89fba2275e3effe12bdc9b6cdc2f4d9eeeHal Canary    sk_sp<const GrGLInterface> gl(GrGLCreateNativeInterface());
6496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == gl.get()) {
65373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        SkDebugf("Context could not create GL interface.\n");
66373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com        this->destroyGLContext();
6730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
6830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
69d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    if (!gl->validate()) {
7030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        SkDebugf("Context could not validate GL interface.\n");
7130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        this->destroyGLContext();
7230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
73373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com    }
74d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton
75d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    fGLLibrary = dlopen(
76d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton        "/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib",
77d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton        RTLD_LAZY);
78d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton
7918300a3aa7cb6eb55d21bb0450dffa58b6fc062cmtklein    this->init(gl.release());
8030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen}
81fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
82273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonMacGLTestContext::~MacGLTestContext() {
83d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    this->teardown();
8430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    this->destroyGLContext();
8530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen}
8630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
87273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonvoid MacGLTestContext::destroyGLContext() {
8830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    if (fContext) {
8930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        CGLReleaseContext(fContext);
9096fcdcc219d2a0d3579719b84b28bede76efba64halcanary        fContext = nullptr;
9130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
92d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    if (RTLD_DEFAULT != fGLLibrary) {
93d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton        dlclose(fGLLibrary);
94d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    }
95373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com}
96373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com
97273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonvoid MacGLTestContext::onPlatformMakeCurrent() const {
98682e1f92455e398804f413d4c223d1d05c4ea2a1bsalomon@google.com    CGLSetCurrentContext(fContext);
99373a6635b7190b4af4d265fdd4b70f102ec3a6fdbsalomon@google.com}
100c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com
101273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonvoid MacGLTestContext::onPlatformSwapBuffers() const {
102c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com    CGLFlushDrawable(fContext);
103c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com}
1049e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen
105273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonGrGLFuncPtr MacGLTestContext::onPlatformGetProcAddress(const char* procName) const {
106d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton    return reinterpret_cast<GrGLFuncPtr>(dlsym(fGLLibrary, procName));
107d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton}
108d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton
1093724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}  // anonymous namespace
1109e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen
1113724e574a744491b7cfb8187ac865a70ef3d4528bsalomonnamespace sk_gpu_test {
112273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomonGLTestContext* CreatePlatformGLTestContext(GrGLStandard forcedGpuAPI,
113273c0f5e87397c40d22bb7e3ee078bb46a3f6860bsalomon                                           GLTestContext* shareContext) {
11430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    if (kGLES_GrGLStandard == forcedGpuAPI) {
11596fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
11630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
11760c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    MacGLTestContext* macShareContext = reinterpret_cast<MacGLTestContext*>(shareContext);
11860c774db3ec46f3eb85f6390ba31e38c8d29e2d4Brian Osman    MacGLTestContext* ctx = new MacGLTestContext(macShareContext);
11930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    if (!ctx->isValid()) {
120385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary        delete ctx;
12196fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
12230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
12330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    return ctx;
1249e61bb7815b133bc40ea7b00fccc853f4b728e3ckkinnunen}
1253724e574a744491b7cfb8187ac865a70ef3d4528bsalomon}  // namespace sk_gpu_test
126