158629291bc145edca8fb303e465c8537bed65314djsollen@google.com 258629291bc145edca8fb303e465c8537bed65314djsollen@google.com/* 358629291bc145edca8fb303e465c8537bed65314djsollen@google.com * Copyright 2011 Google Inc. 458629291bc145edca8fb303e465c8537bed65314djsollen@google.com * 558629291bc145edca8fb303e465c8537bed65314djsollen@google.com * Use of this source code is governed by a BSD-style license that can be 658629291bc145edca8fb303e465c8537bed65314djsollen@google.com * found in the LICENSE file. 758629291bc145edca8fb303e465c8537bed65314djsollen@google.com */ 86c8c34e65ff8248ec7374e0d662d7f5684d800fatomhudson@google.com#include "gl/SkNativeGLContext.h" 958629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1058629291bc145edca8fb303e465c8537bed65314djsollen@google.comSkNativeGLContext::AutoContextRestore::AutoContextRestore() { 1158629291bc145edca8fb303e465c8537bed65314djsollen@google.com fOldEGLContext = eglGetCurrentContext(); 1258629291bc145edca8fb303e465c8537bed65314djsollen@google.com fOldDisplay = eglGetCurrentDisplay(); 1358629291bc145edca8fb303e465c8537bed65314djsollen@google.com fOldSurface = eglGetCurrentSurface(EGL_DRAW); 1458629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1558629291bc145edca8fb303e465c8537bed65314djsollen@google.com} 1658629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1758629291bc145edca8fb303e465c8537bed65314djsollen@google.comSkNativeGLContext::AutoContextRestore::~AutoContextRestore() { 1858629291bc145edca8fb303e465c8537bed65314djsollen@google.com if (NULL != fOldDisplay) { 1958629291bc145edca8fb303e465c8537bed65314djsollen@google.com eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext); 2058629291bc145edca8fb303e465c8537bed65314djsollen@google.com } 2158629291bc145edca8fb303e465c8537bed65314djsollen@google.com} 2258629291bc145edca8fb303e465c8537bed65314djsollen@google.com 2358629291bc145edca8fb303e465c8537bed65314djsollen@google.com/////////////////////////////////////////////////////////////////////////////// 2458629291bc145edca8fb303e465c8537bed65314djsollen@google.com 25fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.comSkNativeGLContext::SkNativeGLContext() 2658629291bc145edca8fb303e465c8537bed65314djsollen@google.com : fContext(EGL_NO_CONTEXT) 2758629291bc145edca8fb303e465c8537bed65314djsollen@google.com , fDisplay(EGL_NO_DISPLAY) 2858629291bc145edca8fb303e465c8537bed65314djsollen@google.com , fSurface(EGL_NO_SURFACE) { 2958629291bc145edca8fb303e465c8537bed65314djsollen@google.com} 3058629291bc145edca8fb303e465c8537bed65314djsollen@google.com 3158629291bc145edca8fb303e465c8537bed65314djsollen@google.comSkNativeGLContext::~SkNativeGLContext() { 3258629291bc145edca8fb303e465c8537bed65314djsollen@google.com this->destroyGLContext(); 3358629291bc145edca8fb303e465c8537bed65314djsollen@google.com} 3458629291bc145edca8fb303e465c8537bed65314djsollen@google.com 3558629291bc145edca8fb303e465c8537bed65314djsollen@google.comvoid SkNativeGLContext::destroyGLContext() { 3658629291bc145edca8fb303e465c8537bed65314djsollen@google.com if (fDisplay) { 3758629291bc145edca8fb303e465c8537bed65314djsollen@google.com eglMakeCurrent(fDisplay, 0, 0, 0); 3858629291bc145edca8fb303e465c8537bed65314djsollen@google.com 3958629291bc145edca8fb303e465c8537bed65314djsollen@google.com if (fContext) { 4058629291bc145edca8fb303e465c8537bed65314djsollen@google.com eglDestroyContext(fDisplay, fContext); 4158629291bc145edca8fb303e465c8537bed65314djsollen@google.com fContext = EGL_NO_CONTEXT; 4258629291bc145edca8fb303e465c8537bed65314djsollen@google.com } 4358629291bc145edca8fb303e465c8537bed65314djsollen@google.com 4458629291bc145edca8fb303e465c8537bed65314djsollen@google.com if (fSurface) { 4558629291bc145edca8fb303e465c8537bed65314djsollen@google.com eglDestroySurface(fDisplay, fSurface); 4658629291bc145edca8fb303e465c8537bed65314djsollen@google.com fSurface = EGL_NO_SURFACE; 4758629291bc145edca8fb303e465c8537bed65314djsollen@google.com } 4858629291bc145edca8fb303e465c8537bed65314djsollen@google.com 4958629291bc145edca8fb303e465c8537bed65314djsollen@google.com //TODO should we close the display? 5058629291bc145edca8fb303e465c8537bed65314djsollen@google.com fDisplay = EGL_NO_DISPLAY; 5158629291bc145edca8fb303e465c8537bed65314djsollen@google.com } 5258629291bc145edca8fb303e465c8537bed65314djsollen@google.com} 5358629291bc145edca8fb303e465c8537bed65314djsollen@google.com 5458629291bc145edca8fb303e465c8537bed65314djsollen@google.comconst GrGLInterface* SkNativeGLContext::createGLContext() { 55f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org static const EGLint kEGLContextAttribsForOpenGL[] = { 56f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org EGL_NONE 57f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org }; 58f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org 59f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org static const EGLint kEGLContextAttribsForOpenGLES[] = { 60f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org EGL_CONTEXT_CLIENT_VERSION, 2, 61f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org EGL_NONE 62f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org }; 63f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org 641e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org static const struct { 651e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org const EGLint* fContextAttribs; 661e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGLenum fAPI; 671e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGLint fRenderableTypeBit; 689e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org GrGLStandard fStandard; 691e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } kAPIs[] = { 701e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org { // OpenGL 711e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org kEGLContextAttribsForOpenGL, 721e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_OPENGL_API, 731e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_OPENGL_BIT, 749e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org kGL_GrGLStandard 751e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org }, 761e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org { // OpenGL ES. This seems to work for both ES2 and 3 (when available). 771e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org kEGLContextAttribsForOpenGLES, 781e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_OPENGL_ES_API, 791e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_OPENGL_ES2_BIT, 809e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org kGLES_GrGLStandard 811e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org }, 821e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org }; 83f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org 841e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org const GrGLInterface* interface = NULL; 85f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org 861e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org for (size_t api = 0; NULL == interface && api < SK_ARRAY_COUNT(kAPIs); ++api) { 871e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 8858629291bc145edca8fb303e465c8537bed65314djsollen@google.com 891e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGLint majorVersion; 901e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGLint minorVersion; 911e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org eglInitialize(fDisplay, &majorVersion, &minorVersion); 92dabdd9e71df4619db0260b9091c9bcc0d57b0a34borenet@google.com 931e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org#if 0 941e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); 951e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); 961e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); 971e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS)); 981e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org#endif 9958629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1001e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org if (!eglBindAPI(kAPIs[api].fAPI)) { 1011e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org continue; 1021e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } 10358629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1041e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGLint numConfigs; 1051e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org const EGLint configAttribs[] = { 1061e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 1071e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit, 1081e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_RED_SIZE, 8, 1091e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_GREEN_SIZE, 8, 1101e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_BLUE_SIZE, 8, 1111e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_ALPHA_SIZE, 8, 1121e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_NONE 1131e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org }; 1141e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org 1151e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGLConfig surfaceConfig; 1161e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) { 1171e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError()); 1181e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org continue; 1191e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } 12058629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1211e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, kAPIs[api].fContextAttribs); 1221e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org if (EGL_NO_CONTEXT == fContext) { 1231e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("eglCreateContext failed. EGL Error: 0x%08x\n", eglGetError()); 1241e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org continue; 1251e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } 12658629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1271e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org static const EGLint kSurfaceAttribs[] = { 1281e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_WIDTH, 1, 1291e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_HEIGHT, 1, 1301e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org EGL_NONE 1311e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org }; 1321e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org 1331e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs); 1341e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org if (EGL_NO_SURFACE == fSurface) { 1351e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError()); 1361e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org this->destroyGLContext(); 1371e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org continue; 1381e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } 13958629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1401e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 1411e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError()); 1421e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org this->destroyGLContext(); 1431e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org continue; 1441e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } 14558629291bc145edca8fb303e465c8537bed65314djsollen@google.com 1461e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org interface = GrGLCreateNativeInterface(); 1471e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org if (NULL == interface) { 1481e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org SkDebugf("Failed to create gl interface.\n"); 1491e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org this->destroyGLContext(); 1501e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org continue; 1511e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } 1521e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org 1539e90aed5de82732cc9921f01388d3063a41a053bcommit-bot@chromium.org if (!interface->validate()) { 1541e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org interface->unref(); 1551e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org interface = NULL; 1561e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org this->destroyGLContext(); 1571e627276c55f1627bef3afa0051685d99443ab1fcommit-bot@chromium.org } 15858629291bc145edca8fb303e465c8537bed65314djsollen@google.com } 159f5897f83e65f18a85f71f2d3357df13c5443e89fcommit-bot@chromium.org 16058629291bc145edca8fb303e465c8537bed65314djsollen@google.com return interface; 16158629291bc145edca8fb303e465c8537bed65314djsollen@google.com} 16258629291bc145edca8fb303e465c8537bed65314djsollen@google.com 16358629291bc145edca8fb303e465c8537bed65314djsollen@google.comvoid SkNativeGLContext::makeCurrent() const { 16458629291bc145edca8fb303e465c8537bed65314djsollen@google.com if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 16558629291bc145edca8fb303e465c8537bed65314djsollen@google.com SkDebugf("Could not set the context.\n"); 16658629291bc145edca8fb303e465c8537bed65314djsollen@google.com } 16758629291bc145edca8fb303e465c8537bed65314djsollen@google.com} 168c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com 169c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.comvoid SkNativeGLContext::swapBuffers() const { 170c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com if (!eglSwapBuffers(fDisplay, fSurface)) { 171c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com SkDebugf("Could not complete eglSwapBuffers.\n"); 172c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com } 173c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com} 174