Home | History | Annotate | Download | only in android
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "gl/SkNativeGLContext.h"
      9 
     10 SkNativeGLContext::AutoContextRestore::AutoContextRestore() {
     11     fOldEGLContext = eglGetCurrentContext();
     12     fOldDisplay = eglGetCurrentDisplay();
     13     fOldSurface = eglGetCurrentSurface(EGL_DRAW);
     14 
     15 }
     16 
     17 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() {
     18     if (fOldDisplay) {
     19         eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext);
     20     }
     21 }
     22 
     23 ///////////////////////////////////////////////////////////////////////////////
     24 
     25 SkNativeGLContext::SkNativeGLContext()
     26     : fContext(EGL_NO_CONTEXT)
     27     , fDisplay(EGL_NO_DISPLAY)
     28     , fSurface(EGL_NO_SURFACE) {
     29 }
     30 
     31 SkNativeGLContext::~SkNativeGLContext() {
     32     this->destroyGLContext();
     33 }
     34 
     35 void SkNativeGLContext::destroyGLContext() {
     36     if (fDisplay) {
     37         eglMakeCurrent(fDisplay, 0, 0, 0);
     38 
     39         if (fContext) {
     40             eglDestroyContext(fDisplay, fContext);
     41             fContext = EGL_NO_CONTEXT;
     42         }
     43 
     44         if (fSurface) {
     45             eglDestroySurface(fDisplay, fSurface);
     46             fSurface = EGL_NO_SURFACE;
     47         }
     48 
     49         //TODO should we close the display?
     50         fDisplay = EGL_NO_DISPLAY;
     51     }
     52 }
     53 
     54 const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAPI) {
     55     static const EGLint kEGLContextAttribsForOpenGL[] = {
     56         EGL_NONE
     57     };
     58 
     59     static const EGLint kEGLContextAttribsForOpenGLES[] = {
     60         EGL_CONTEXT_CLIENT_VERSION, 2,
     61         EGL_NONE
     62     };
     63 
     64     static const struct {
     65         const EGLint* fContextAttribs;
     66         EGLenum fAPI;
     67         EGLint  fRenderableTypeBit;
     68         GrGLStandard fStandard;
     69     } kAPIs[] = {
     70         {   // OpenGL
     71             kEGLContextAttribsForOpenGL,
     72             EGL_OPENGL_API,
     73             EGL_OPENGL_BIT,
     74             kGL_GrGLStandard
     75         },
     76         {   // OpenGL ES. This seems to work for both ES2 and 3 (when available).
     77             kEGLContextAttribsForOpenGLES,
     78             EGL_OPENGL_ES_API,
     79             EGL_OPENGL_ES2_BIT,
     80             kGLES_GrGLStandard
     81         },
     82     };
     83 
     84     size_t apiLimit = SK_ARRAY_COUNT(kAPIs);
     85     size_t api = 0;
     86     if (forcedGpuAPI == kGL_GrGLStandard) {
     87         apiLimit = 1;
     88     } else if (forcedGpuAPI == kGLES_GrGLStandard) {
     89         api = 1;
     90     }
     91     SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == forcedGpuAPI);
     92 
     93     const GrGLInterface* interface = NULL;
     94 
     95     for (; NULL == interface && api < apiLimit; ++api) {
     96         fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     97 
     98         EGLint majorVersion;
     99         EGLint minorVersion;
    100         eglInitialize(fDisplay, &majorVersion, &minorVersion);
    101 
    102 #if 0
    103         SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR));
    104         SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS));
    105         SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION));
    106         SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS));
    107 #endif
    108 
    109         if (!eglBindAPI(kAPIs[api].fAPI)) {
    110             continue;
    111         }
    112 
    113         EGLint numConfigs;
    114         const EGLint configAttribs[] = {
    115             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
    116             EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit,
    117             EGL_RED_SIZE, 8,
    118             EGL_GREEN_SIZE, 8,
    119             EGL_BLUE_SIZE, 8,
    120             EGL_ALPHA_SIZE, 8,
    121             EGL_NONE
    122         };
    123 
    124         EGLConfig surfaceConfig;
    125         if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) {
    126             SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError());
    127             continue;
    128         }
    129 
    130         fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, kAPIs[api].fContextAttribs);
    131         if (EGL_NO_CONTEXT == fContext) {
    132             SkDebugf("eglCreateContext failed.  EGL Error: 0x%08x\n", eglGetError());
    133             continue;
    134         }
    135 
    136         static const EGLint kSurfaceAttribs[] = {
    137             EGL_WIDTH, 1,
    138             EGL_HEIGHT, 1,
    139             EGL_NONE
    140         };
    141 
    142         fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs);
    143         if (EGL_NO_SURFACE == fSurface) {
    144             SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError());
    145             this->destroyGLContext();
    146             continue;
    147         }
    148 
    149         if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
    150             SkDebugf("eglMakeCurrent failed.  EGL Error: 0x%08x\n", eglGetError());
    151             this->destroyGLContext();
    152             continue;
    153         }
    154 
    155         interface = GrGLCreateNativeInterface();
    156         if (NULL == interface) {
    157             SkDebugf("Failed to create gl interface.\n");
    158             this->destroyGLContext();
    159             continue;
    160         }
    161 
    162         if (!interface->validate()) {
    163             interface->unref();
    164             interface = NULL;
    165             this->destroyGLContext();
    166         }
    167     }
    168 
    169     return interface;
    170 }
    171 
    172 void SkNativeGLContext::makeCurrent() const {
    173     if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
    174         SkDebugf("Could not set the context.\n");
    175     }
    176 }
    177 
    178 void SkNativeGLContext::swapBuffers() const {
    179     if (!eglSwapBuffers(fDisplay, fSurface)) {
    180         SkDebugf("Could not complete eglSwapBuffers.\n");
    181     }
    182 }
    183